Compare commits

...

14 Commits

Author SHA1 Message Date
m3tm3re
eb06533174 Merge feature/home-profile-restructuring: home-manager profile refactoring
Refactor home-manager configuration structure:
- Reorganize from features/ to base/coding/desktop/server/profiles/
- Add language runtime modules (go, js, python, rust, typescript)
- Add LSP server configuration
- Add gaming and media profiles
- Add shell modules (fish, nushell, starship)
- Consolidate editor and git configuration
2026-04-26 13:53:00 +02:00
m3tm3re
30a9a23de2 refactor: add language runtimes module and cleanup agent config
- Add home/coding/languages/ with Python, JavaScript, Rust, Go, TypeScript
- Move bun/nodejs from agents.nix to languages/javascript.nix
- Move python3 with packages to languages/python.nix
- Move npm config to javascript.nix (broader context)
- Add language options to m3-ares and m3-kratos host configs
- Move pyrefly from agents.nix to lsp/servers.nix
- Remove duplicate python3 reference (build conflict fix)
- Remove unused base/secrets/cli-tools/ duplicates
2026-04-26 13:20:22 +02:00
m3tm3re
6d0149ee6e feat: add AMD GPU tools, media packages, and productivity module
Task 3 - Gaming profile:
- Add gpu.nix with ROCm runtime/smi/info and vulkan-tools
- Import gpu.nix in gaming profile aggregator

Task 4 - Media profile:
- Add unimatrix to yt-dlp.nix packages
- (plexamp, webcord, mpv config were already present)

Task 5 - Desktop apps:
- Add productivity.nix with pomodoro-timer
- Import productivity.nix in desktop apps aggregator
2026-04-26 12:32:47 +02:00
m3tm3re
d19b87f8cd feat: add coding packages module (bruno, insomnia) 2026-04-26 12:29:14 +02:00
m3tm3re
8f5d076d7b fix: make base modules enabled by default; document lazylib→lazygit
- All base/* modules now use (mkEnableOption "...") // { default = true; }
  so they activate automatically when imported — no explicit .enable = true
  required in host configs
- packages.nix: add comment documenting that lazylib does not exist in
  nixpkgs; lazygit is the correct and intended package
- zellij-ps.nix: clarify that cli.zellij-ps namespace is intentional —
  it is the home-manager module convention from m3ta-nixpkgs
- nix flake check passes (warnings are pre-existing)
2026-04-26 12:16:44 +02:00
m3tm3re
3c9a107608 feat: add missing packages and programs to base cli-tools
- packages.nix: essential packages (jq, ripgrep, fd, htop, coreutils,
  lazygit, httpie, just, devenv, gcc, go, sqlite, sqlite-vec, nix-index,
  nix-update, progress, comma, fabric-ai, llm, basecamp, hyprpaper-random,
  libnotify, trash-cli, unzip, zip, yazi)
- bat.nix: bat with nix-colors derived syntax theme
- carapace.nix: multi-shell completion (fish, nushell, bash)
- direnv.nix: automatic env loading with nix-direnv
- eza.nix: modern ls with icons, git status, long format
- lf.nix: terminal file manager with bat preview
- zoxide.nix: smarter cd with fish and nushell integration
- zellij-ps.nix: project session manager wrapping cli.zellij-ps
2026-04-26 12:06:36 +02:00
m3tm3re
cc01c1d0aa fix(agents): make videoDrivers optional with safe default
For standalone Home Manager evaluation where videoDrivers may be absent
2026-04-26 11:37:17 +02:00
m3tm3re
d59a6b82b6 chore: remove features.old archive and format all files
- Delete home/features.old/ (archived old flat feature modules)
- All content migrated to new profile-based structure
- Run alejandra formatter over 13 changed files
- nix flake check passes cleanly
2026-04-26 11:29:49 +02:00
m3tm3re
d44bdad73a refactor: archive old features directory to features.old
The new profile-based structure (home/base, home/desktop, home/server,
home/profiles/, home/coding) is fully operational and imported via
home/lib/mkHomeConfig. The legacy home/features directory is no longer
referenced anywhere in the configuration.

Archived rather than deleted to preserve history for reference.
2026-04-26 11:22:17 +02:00
m3tm3re
797ffb2b8a fix: assert unknown profiles in mkHomeConfig; move agent modules to coding/agents
- home/lib/default.nix: add assertion for unknown profile names instead of
  silently filtering them out; remove unused 'inherit (lib) optional'
- home/coding/agents/{opencode,pi}.nix: moved from home/features/coding/
  to co-locate with agents.nix (eliminating cross-directory back-references)
- home/coding/agents/agents.nix: update imports to ./opencode.nix and ./pi.nix
- home/features/coding/: remove now-dead default.nix (nothing imported it)
2026-04-26 11:17:03 +02:00
m3tm3re
73bd2b1f2e fix: spec review - add missing fish module to base/shell
- Create home/base/shell/fish.nix
- Add to base/shell/default.nix imports
- Migrate remaining hosts from features.cli.fish to base.shell.fish
2026-04-26 11:09:50 +02:00
m3tm3re
f3749c5679 feat: implement profile system with mkHomeConfig and context constraints
- Add home/lib/default.nix with mkHomeConfig utility
  - Loads base + common modules always
  - Maps profiles (coding, gaming, media) to module imports
  - Enforces desktop/server mutual exclusion via assertion
  - Context must be 'desktop', 'server', or null

- Migrate all per-host home configs to new profile system
  - m3-ares: context=desktop, profiles=[coding, gaming, media]
  - m3-kratos: context=desktop, profiles=[coding, gaming, media]
  - m3-atlas: context=server, profiles=[coding]
  - m3-helios: context=server, profiles=[]
  - m3-hermes: context=server, profiles=[]
  - m3-aether: context=server, profiles=[]
  - m3-daedalus: context=desktop, profiles=[coding, media]

- Replace features.* options with new namespaces:
  - features.cli.* -> base.shell.* / base.cliTools.* / base.secrets
  - features.desktop.* -> desktop.wm.* / desktop.apps.* / desktop.theme.*
  - gaming/media moved to profiles.gaming.* / profiles.media.*

- Fix home/coding/editor/neovim.nix: remove duplicate option declaration
  (coding.editors.neovim.enable already declared by m3ta-nixpkgs)

- Fix home/coding/lsp/servers.nix: replace removed nodePackages.typescript-language-server
  with typescript-language-server

- Fix home/desktop/theme/wallpapers.nix: correct relative path
  (was ../../.. which resolved to project root, should be ../..)
2026-04-26 11:03:43 +02:00
m3tm3re
9908b9e335 fix: code review fixes
- Fix hardcoded user path in webapps.nix (use homeDirectory)
- Normalize wallpapers option to use .enable suffix
- Remove duplicate FZF keybind declaration
- Update comments to match actual implementation
2026-04-26 10:49:01 +02:00
m3tm3re
1b5bcae686 feat: create new home/ directory structure for profile-based config
New structure:
- home/base/        - Always loaded (shell, cli-tools, secrets)
- home/coding/      - Profile-independent dev tooling (editor, lsp, git, agents)
- home/profiles/    - Freely combinable profiles (gaming, media)
- home/desktop/     - Desktop-only (wm, apps, theme)
- home/server/      - Minimal server stub

Migration sources:
- home/features/cli/ → home/base/{shell,cli-tools,secrets}
- home/features/desktop/hyprland,wayland,rofi → home/desktop/wm/
- home/features/desktop/obsidian,office,webapps,crypto → home/desktop/apps/
- home/features/desktop/fonts,theme,wallpapers → home/desktop/theme/
- gaming.nix split → home/profiles/gaming/{steam,gamescope}
- media.nix split  → home/profiles/media/{obs,ffmpeg,yt-dlp,kdenlive,handbrake}

Option namespaces updated:
- features.cli.*  → base.shell.* / base.cliTools.* / base.secrets
- features.desktop.* → desktop.wm.* / desktop.apps.* / desktop.theme.*
- features.desktop.gaming → profiles.gaming.*
- features.desktop.media  → profiles.media.*

Verified: nix flake check passes (warnings only)
2026-04-26 10:37:03 +02:00
87 changed files with 1521 additions and 1183 deletions

View File

@@ -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)

View File

@@ -9,7 +9,8 @@ with lib; let
cfg = config.base.cliTools.bat; cfg = config.base.cliTools.bat;
palette = config.colorScheme.palette; palette = config.colorScheme.palette;
in { 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 { config = mkIf cfg.enable {
programs.bat = { programs.bat = {

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.carapace; cfg = config.base.cliTools.carapace;
in { 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 { config = mkIf cfg.enable {
programs.carapace = { programs.carapace = {

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.direnv; cfg = config.base.cliTools.direnv;
in { 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 { config = mkIf cfg.enable {
programs.direnv = { programs.direnv = {

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.eza; cfg = config.base.cliTools.eza;
in { 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 { config = mkIf cfg.enable {
programs.eza = { programs.eza = {

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.fzf; cfg = config.base.cliTools.fzf;
in { 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 { config = mkIf cfg.enable {
programs.fzf = { programs.fzf = {

View File

@@ -8,7 +8,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.lf; cfg = config.base.cliTools.lf;
in { 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 { config = mkIf cfg.enable {
home.packages = [pkgs.lf]; home.packages = [pkgs.lf];

View File

@@ -8,7 +8,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.nitch; cfg = config.base.cliTools.nitch;
in { 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 { config = mkIf cfg.enable {
home.packages = [pkgs.nitch]; home.packages = [pkgs.nitch];

View File

@@ -1,4 +1,6 @@
# Essential CLI packages — core utilities always available on every host. # 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, config,
lib, lib,
@@ -8,7 +10,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.essentials; cfg = config.base.cliTools.essentials;
in { 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 { config = mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [
@@ -19,22 +22,30 @@ in {
jq jq
ripgrep ripgrep
# Nix
alejandra
comma
nixd
nix-diff
nix-index
nix-update
# Dev tools # Dev tools
bc
cmake
devenv devenv
gcc gcc
gnumake
go go
httpie httpie
just just
lazygit lazygit
nix-index
nix-update
progress progress
sqlite sqlite
sqlite-vec sqlite-vec
tldr tldr
# AI tools # AI tools
comma
fabric-ai fabric-ai
llm llm

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.television; cfg = config.base.cliTools.television;
in { 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 { config = mkIf cfg.enable {
programs.television = { programs.television = {

View File

@@ -1,5 +1,7 @@
# Zellij-ps — project-aware Zellij session manager from m3ta-nixpkgs. # 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, config,
lib, lib,
@@ -9,7 +11,8 @@ with lib; let
cfg = config.base.cliTools.zellijPs; cfg = config.base.cliTools.zellijPs;
in { in {
options.base.cliTools.zellijPs = { 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 { projectFolders = mkOption {
type = types.listOf types.path; type = types.listOf types.path;

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.zellij; cfg = config.base.cliTools.zellij;
in { 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 { config = mkIf cfg.enable {
programs.zellij = { programs.zellij = {

View File

@@ -7,7 +7,8 @@
with lib; let with lib; let
cfg = config.base.cliTools.zoxide; cfg = config.base.cliTools.zoxide;
in { 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 { config = mkIf cfg.enable {
programs.zoxide = { programs.zoxide = {

9
home/base/default.nix Normal file
View File

@@ -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
];
}

View File

@@ -1,3 +1,4 @@
# Password store and secrets management via pass-wayland with OTP and import extensions.
{ {
config, config,
lib, lib,
@@ -5,9 +6,10 @@
... ...
}: }:
with lib; let with lib; let
cfg = config.features.cli.secrets; cfg = config.base.secrets;
in { 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 { config = mkIf cfg.enable {
programs.password-store = { programs.password-store = {
@@ -17,6 +19,6 @@ in {
(exts: [exts.pass-otp exts.pass-import]); (exts: [exts.pass-otp exts.pass-import]);
settings = {PASSWORD_STORE_DIR = "$XDG_DATA_HOME/password-store";}; settings = {PASSWORD_STORE_DIR = "$XDG_DATA_HOME/password-store";};
}; };
home.packages = with pkgs; [pinentry-gnome3]; home.packages = [pkgs.pinentry-gnome3];
}; };
} }

View File

@@ -0,0 +1,8 @@
# Shell aggregator — imports Nushell (primary), Fish, and Starship prompt.
{...}: {
imports = [
./nushell.nix
./fish.nix
./starship.nix
];
}

View File

@@ -1,12 +1,14 @@
# Fish shell configuration exposed under the new base namespace.
{ {
config, config,
lib, lib,
... ...
}: }:
with lib; let with lib; let
cfg = config.features.cli.fish; cfg = config.base.shell.fish;
in { 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 { config = mkIf cfg.enable {
programs.fish = { programs.fish = {

View File

@@ -1,12 +1,14 @@
# Primary shell configuration — Nushell with environment, aliases, and integrations.
{ {
config, config,
lib, lib,
... ...
}: }:
with lib; let with lib; let
cfg = config.features.cli.nushell; cfg = config.base.shell.nushell;
in { 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 { config = mkIf cfg.enable {
programs.nushell = { programs.nushell = {
@@ -20,9 +22,8 @@ in {
$env.EDITOR = "nvim" $env.EDITOR = "nvim"
$env.VISUAL = "zeditor" $env.VISUAL = "zeditor"
$env.FZF_DEFAULT_COMMAND = "fd --type f --exclude .git --follow --hidden" $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.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.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.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" $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 = '' configFile.text = ''
# Aliases # Aliases
alias .. = cd .. alias .. = cd ..

View File

@@ -1,12 +1,14 @@
# Starship cross-shell prompt with nix-colors theming.
{ {
config, config,
lib, lib,
... ...
}: }:
with lib; let with lib; let
cfg = config.features.cli.starship; cfg = config.base.shell.starship;
in { 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 { config = mkIf cfg.enable {
programs.starship = { programs.starship = {

View File

@@ -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, config,
inputs, inputs,
lib,
pkgs, pkgs,
videoDrivers, videoDrivers ? [],
... ...
}: let }: {
npmGlobalPrefix = "${config.home.homeDirectory}/.npm-global";
in {
home.file.".npmrc".text = ''
prefix=${npmGlobalPrefix}
'';
home.sessionVariables.NPM_CONFIG_PREFIX = npmGlobalPrefix;
imports = [ imports = [
# OpenCode and Pi agent configurations
./opencode.nix ./opencode.nix
./pi.nix ./pi.nix
]; ];
@@ -64,39 +63,12 @@ in {
home.packages = with pkgs; [ home.packages = with pkgs; [
agenix-cli agenix-cli
agent-browser agent-browser
alejandra
bc
bun
devpod
#devpod-desktop
gnumake
cmake
(python3.withPackages (ps:
with ps; [
pip
uv
# Scientific packages
numba
numpy
torch
srt
]))
pyrefly pyrefly
nixd
nix-update
nodejs
# opencode-desktop
(qmd.override { (qmd.override {
vulkanSupport = videoDrivers == ["amdgpu"]; vulkanSupport = videoDrivers == ["amdgpu"];
cudaSupport = videoDrivers == ["nvidia"]; cudaSupport = videoDrivers == ["nvidia"];
}) })
openshell openshell
openspec openspec
pi-coding-agent
alejandra
sidecar
tailwindcss
tailwindcss-language-server
td
]; ];
} }

View File

@@ -41,7 +41,6 @@
"npm:@plannotator/pi-extension" "npm:@plannotator/pi-extension"
"npm:pi-powerline-footer" "npm:pi-powerline-footer"
"npm:pi-markdown-preview" "npm:pi-markdown-preview"
"npm:pi-gsd"
"npm:pi-tool-display" "npm:pi-tool-display"
"npm:pi-agent-browser-native" "npm:pi-agent-browser-native"
"git:github.com/hk-vk/pi-connect" "git:github.com/hk-vk/pi-connect"

12
home/coding/default.nix Normal file
View File

@@ -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
];
}

View File

@@ -0,0 +1,6 @@
# Editor aggregator — delegates to m3ta-nixpkgs editor modules.
{...}: {
imports = [
./neovim.nix
];
}

View File

@@ -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.
}

41
home/coding/git/git.nix Normal file
View File

@@ -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
];
}

View File

@@ -0,0 +1,10 @@
# Language runtimes — Python, JavaScript, Rust, Go, TypeScript.
{...}: {
imports = [
./python.nix
./javascript.nix
./rust-toolchain.nix
./go.nix
./typescript.nix
];
}

View File

@@ -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
];
};
}

View File

@@ -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;
};
}

View File

@@ -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))
];
};
}

View File

@@ -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
];
};
}

View File

@@ -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
];
};
}

View File

@@ -0,0 +1,6 @@
# LSP aggregator — language server protocol tooling.
{...}: {
imports = [
./servers.nix
];
}

View File

@@ -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
];
};
}

20
home/coding/packages.nix Normal file
View File

@@ -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
];
};
}

View File

@@ -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];
};
}

View File

@@ -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
];
}

View File

@@ -1,13 +1,13 @@
# Obsidian knowledge base with markdown MIME association.
{ {
config, config,
lib, lib,
... ...
}: }:
with lib; let with lib; let
cfg = config.features.desktop.obsidian; cfg = config.desktop.apps.obsidian;
in { in {
options.features.desktop.obsidian.enable = options.desktop.apps.obsidian.enable = mkEnableOption "enable Obsidian knowledge base";
mkEnableOption "enable Obsidian knowledge base";
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.obsidian.enable = true; programs.obsidian.enable = true;

View File

@@ -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];
};
}

View File

@@ -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
];
};
}

View File

@@ -1,6 +1,7 @@
# Web application desktop entries — Teams, Outlook, Basecamp, and OpenCode launchers.
{ {
config,
pkgs, pkgs,
lib,
... ...
}: let }: let
icons = { icons = {
@@ -41,7 +42,7 @@ in {
comment = "Open Basecamp as a Desktop App"; comment = "Open Basecamp as a Desktop App";
categories = ["Application" "Network"]; categories = ["Application" "Network"];
terminal = false; terminal = false;
icon = "/home/sascha.koenig/.local/share/icons/basecamp-logo.png"; icon = "${config.home.homeDirectory}/.local/share/icons/basecamp-logo.png";
}; };
opencode = { opencode = {
name = "Opencode"; name = "Opencode";

View File

@@ -1,22 +1,14 @@
# Desktop environment aggregator — only loaded when context=desktop.
# Includes window manager, applications, theming, and desktop session config.
{ {
config, config,
pkgs, pkgs,
... ...
}: { }: {
imports = [ imports = [
./coding.nix ./wm
./crypto.nix ./apps
./fonts.nix ./theme
./gaming.nix
./hyprland.nix
./media.nix
./obsidian.nix
./office.nix
./rofi.nix
./theme.nix
./wallpapers.nix
./wayland.nix
./webapps.nix
]; ];
xdg = { xdg = {
@@ -55,7 +47,13 @@
XDG_SESSION_TYPE = "wayland"; XDG_SESSION_TYPE = "wayland";
XDG_SESSION_DESKTOP = "Hyprland"; 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; fonts.fontconfig.enable = true;
@@ -66,17 +64,11 @@
settings = { settings = {
font-family = "Fira Code"; font-family = "Fira Code";
copy-on-select = true; copy-on-select = true;
# Base colors from nix-colors
foreground = "#${config.colorScheme.palette.base05}"; foreground = "#${config.colorScheme.palette.base05}";
background = "#${config.colorScheme.palette.base00}"; background = "#${config.colorScheme.palette.base00}";
selection-foreground = "#${config.colorScheme.palette.base07}"; selection-foreground = "#${config.colorScheme.palette.base07}";
selection-background = "#${config.colorScheme.palette.base02}"; selection-background = "#${config.colorScheme.palette.base02}";
# Cursor
cursor-color = "#${config.colorScheme.palette.base05}"; cursor-color = "#${config.colorScheme.palette.base05}";
# Palette (16 colors)
palette = [ palette = [
"0=#${config.colorScheme.palette.base01}" "0=#${config.colorScheme.palette.base01}"
"1=#${config.colorScheme.palette.base08}" "1=#${config.colorScheme.palette.base08}"
@@ -107,56 +99,27 @@
home.packages = with pkgs; [ home.packages = with pkgs; [
appimage-run appimage-run
# blueberry
bemoji bemoji
brave brave
# brightnessctl
# clipman
distrobox distrobox
eigent eigent
(element-desktop.override { (element-desktop.override {
commandLineArgs = "--password-store=gnome-libsecret"; commandLineArgs = "--password-store=gnome-libsecret";
}) })
launch-webapp launch-webapp
# eww
# firefox-devedition
file-roller file-roller
hyprpanel hyprpanel
seahorse seahorse
sushi sushi
# glib
# google-chrome
# gsettings-desktop-schemas
# graphviz
ksnip ksnip
msty-studio msty-studio
nwg-look nwg-look
# opencode-desktop
# pamixer
# pavucontrol
# libsForQt5.qtstyleplugins
# stable.nyxt
# pcmanfm
rose-pine-hyprcursor rose-pine-hyprcursor
# qt5ct
# qt6.qtwayland
#rustdesk
# socat
# unrar
# unzip
# usbutils
# v4l-utils
remmina remmina
slack slack
telegram-desktop telegram-desktop
vivaldi vivaldi
vivaldi-ffmpeg-codecs vivaldi-ffmpeg-codecs
vibetyper vibetyper
# wl-clipboard
# wlogout
# wtype
# xdg-utils
# ydotool
# zip
]; ];
} }

View File

@@ -0,0 +1,8 @@
# Theme aggregator — fonts, GTK/Qt theming, and wallpapers.
{...}: {
imports = [
./fonts.nix
./theme.nix
./wallpapers.nix
];
}

View File

@@ -1,3 +1,4 @@
# Font packages — Fira Code, JetBrains Mono Nerd Font, and supporting icon fonts.
{ {
config, config,
lib, lib,
@@ -5,10 +6,9 @@
... ...
}: }:
with lib; let with lib; let
cfg = config.features.desktop.fonts; cfg = config.desktop.theme.fonts;
in { in {
options.features.desktop.fonts.enable = options.desktop.theme.fonts.enable = mkEnableOption "install desktop fonts";
mkEnableOption "install additional fonts for desktop apps";
config = mkIf cfg.enable { config = mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [

View File

@@ -1,12 +1,14 @@
# GTK and Qt theming — Dracula theme with matching icons and cursor.
{ {
config,
pkgs, pkgs,
config,
... ...
}: { }: {
qt = { qt = {
enable = true; enable = true;
platformTheme.name = "gtk"; platformTheme.name = "gtk";
}; };
gtk = { gtk = {
enable = true; enable = true;
theme = { theme = {

View File

@@ -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;
};
};
}

View File

@@ -0,0 +1,8 @@
# Window manager aggregator — Hyprland, Wayland tools, and Rofi launcher.
{...}: {
imports = [
./hyprland.nix
./wayland.nix
./rofi.nix
];
}

View File

@@ -1,13 +1,13 @@
# Hyprland window manager with keybindings, window rules, idle/lock, and hyprpaper.
{ {
config, config,
lib, lib,
... ...
}: }:
with lib; let with lib; let
cfg = config.features.desktop.hyprland; cfg = config.desktop.wm.hyprland;
in { in {
options.features.desktop.hyprland.enable = options.desktop.wm.hyprland.enable = mkEnableOption "Hyprland window manager";
mkEnableOption "Hyprland related stuff";
config = mkIf cfg.enable { config = mkIf cfg.enable {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
@@ -19,8 +19,8 @@ in {
exec-once = [ exec-once = [
"hyprpanel" "hyprpanel"
"while ! hyprpaper-random; do sleep 0.5; done" "while ! hyprpaper-random; do sleep 0.5; done"
"wl-paste --type text --watch cliphist store" # Stores only text data "wl-paste --type text --watch cliphist store"
"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 image --watch cliphist store"
"vibetyper" "vibetyper"
]; ];
@@ -49,7 +49,6 @@ in {
gaps_in = 5; gaps_in = 5;
gaps_out = 5; gaps_out = 5;
border_size = 1; border_size = 1;
# Keeping the existing active border as requested
"col.active_border" = "rgba(9742b5ee) rgba(9742b5ee) 45deg"; "col.active_border" = "rgba(9742b5ee) rgba(9742b5ee) 45deg";
"col.inactive_border" = "rgba(${config.colorScheme.palette.base03}aa)"; "col.inactive_border" = "rgba(${config.colorScheme.palette.base03}aa)";
layout = "dwindle"; layout = "dwindle";
@@ -110,8 +109,8 @@ in {
kb_layout = "us"; kb_layout = "us";
} }
]; ];
windowrule = [ windowrule = [
# Floating dialogs
"match:class file_progress, float on" "match:class file_progress, float on"
"match:class confirm, float on" "match:class confirm, float on"
"match:class dialog, float on" "match:class dialog, float on"
@@ -125,24 +124,19 @@ in {
"match:class pavucontrol-qt, float on" "match:class pavucontrol-qt, float on"
"match:class pavucontrol, float on" "match:class pavucontrol, float on"
"match:class class:^(espanso)$, float on" "match:class class:^(espanso)$, float on"
# wlogout
"match:class wlogout, fullscreen on" "match:class wlogout, fullscreen on"
"match:title wlogout, float on" "match:title wlogout, float on"
"match:title wlogout, fullscreen on" "match:title wlogout, fullscreen on"
# mpv
"match:class mpv, float on" "match:class mpv, float on"
"match:class mpv, idle_inhibit focus" "match:class mpv, idle_inhibit focus"
"match:class mpv, opacity 1.0 override" "match:class mpv, opacity 1.0 override"
# Media/Volume/PiP
"match:title ^(Media viewer)$, float on" "match:title ^(Media viewer)$, float on"
"match:title ^(Volume Control)$, float on" "match:title ^(Volume Control)$, float on"
"match:title ^(Picture-in-Picture)$, float on" "match:title ^(Picture-in-Picture)$, float on"
# Pomodoro timer
"match:title ^(floating-pomodoro)$, float on" "match:title ^(floating-pomodoro)$, float on"
"match:title ^(floating-pomodoro)$, size 250 50" "match:title ^(floating-pomodoro)$, size 250 50"
"match:title ^(floating-pomodoro)$, move 12 (monitor_h-150)" "match:title ^(floating-pomodoro)$, move 12 (monitor_h-150)"
"match:title ^(floating-pomodoro)$, pin on" "match:title ^(floating-pomodoro)$, pin on"
# Streamlabs overlays
"match:initial_title .*streamlabs.com.*, float on" "match:initial_title .*streamlabs.com.*, float on"
"match:initial_title .*streamlabs.com.*, pin on" "match:initial_title .*streamlabs.com.*, pin on"
"match:initial_title .*streamlabs.com.*, size 800 400" "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.*, decorate off"
"match:initial_title .*streamlabs.com.*, no_shadow on" "match:initial_title .*streamlabs.com.*, no_shadow on"
"match:initial_title .*streamlabs.com.*, no_blur on" "match:initial_title .*streamlabs.com.*, no_blur on"
# Vibetyper recording indicator
"match:class ^vibe-typer$, match:title ^Recording Indicator$, no_blur on" "match:class ^vibe-typer$, match:title ^Recording Indicator$, no_blur on"
"border_color rgb(ffffff), match:xwayland 1" "border_color rgb(ffffff), match:xwayland 1"
]; ];
"$mainMod" = "SUPER"; "$mainMod" = "SUPER";
"$terminal" = "ghostty"; "$terminal" = "ghostty";
bind = [ bind = [
"$mainMod, return, exec, $terminal nu -c zellij-ps" "$mainMod, return, exec, $terminal nu -c zellij-ps"
# "$mainMod, t, exec, warp-terminal"
"$mainMod, t, exec, $terminal -e nu -c 'nitch; exec nu'" "$mainMod, t, exec, $terminal -e nu -c 'nitch; exec nu'"
"$mainMod SHIFT, t, exec, launch-timer" "$mainMod SHIFT, t, exec, launch-timer"
"$mainMod, n, exec, $terminal -e nvim" "$mainMod, n, exec, $terminal -e nvim"
@@ -214,16 +207,19 @@ in {
"$mainMod, mouse_down, workspace, e+1" "$mainMod, mouse_down, workspace, e+1"
"$mainMod, mouse_up, workspace, e-1" "$mainMod, mouse_up, workspace, e-1"
]; ];
bindr = [ bindr = [
"$mainMod, R, exec, stt-ptt stop" "$mainMod, R, exec, stt-ptt stop"
"$mainMod, S, exec, stt-ptt format-stop" "$mainMod, S, exec, stt-ptt format-stop"
]; ];
bindm = [ bindm = [
"$mainMod, mouse:272, movewindow" "$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow" "$mainMod, mouse:273, resizewindow"
]; ];
}; };
}; };
services.hypridle = { services.hypridle = {
enable = true; enable = true;
settings = { settings = {
@@ -232,14 +228,13 @@ in {
after_sleep_cmd = "hyprctl dispatch dpms on"; after_sleep_cmd = "hyprctl dispatch dpms on";
inhibit_sleep = 3; inhibit_sleep = 3;
}; };
listener = [ listener = [
{ {
timeout = 300; # 5 min timeout = 300;
on-timeout = "hyprlock"; on-timeout = "hyprlock";
} }
{ {
timeout = 420; # 5.5 min timeout = 420;
on-timeout = "hyprctl dispatch dpms off"; on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on"; on-resume = "hyprctl dispatch dpms on";
} }

View File

@@ -1,3 +1,4 @@
# Rofi application launcher with nix-colors theme, pass integration, and project opener.
{ {
config, config,
pkgs, pkgs,
@@ -5,23 +6,23 @@
... ...
}: }:
with lib; let with lib; let
cfg = config.features.desktop.rofi; cfg = config.desktop.wm.rofi;
in { in {
options.features.desktop.rofi.enable = mkEnableOption "enable rofi"; options.desktop.wm.rofi.enable = mkEnableOption "enable rofi";
config = mkIf cfg.enable { config = mkIf cfg.enable {
programs.rofi = with pkgs; { programs.rofi = {
enable = true; enable = true;
package = rofi.override { package = pkgs.rofi.override {
plugins = [ plugins = [
rofi-calc pkgs.rofi-calc
rofi-emoji pkgs.rofi-emoji
stable.rofi-file-browser pkgs.stable.rofi-file-browser
]; ];
}; };
pass = { pass = {
enable = true; enable = true;
package = rofi-pass-wayland; package = pkgs.rofi-pass-wayland;
}; };
terminal = "${pkgs.ghostty}/bin/ghostty"; terminal = "${pkgs.ghostty}/bin/ghostty";
font = "Fira Code"; font = "Fira Code";
@@ -169,7 +170,6 @@ in {
text-color: @background; text-color: @background;
} }
/* Scrollbar */
scrollbar { scrollbar {
width: 4px; width: 4px;
border: 0; border: 0;
@@ -179,6 +179,7 @@ in {
} }
''); '');
}; };
cli.rofi-project-opener = { cli.rofi-project-opener = {
enable = true; enable = true;
projectDirs = { projectDirs = {

View File

@@ -1,3 +1,4 @@
# Wayland extra tooling — screenshot, clipboard, cursor, and display utilities.
{ {
config, config,
lib, lib,
@@ -5,9 +6,9 @@
... ...
}: }:
with lib; let with lib; let
cfg = config.features.desktop.wayland; cfg = config.desktop.wm.wayland;
in { 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 { config = mkIf cfg.enable {
home.packages = with pkgs; [ home.packages = with pkgs; [

View File

@@ -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

View File

@@ -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" ''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>Universal (nix-colors)</string>
<key>settings</key>
<array>
<dict>
<key>settings</key>
<dict>
<key>background</key>
<string>#${config.colorScheme.palette.base00}</string>
<key>foreground</key>
<string>#${config.colorScheme.palette.base05}</string>
<key>caret</key>
<string>#${config.colorScheme.palette.base05}</string>
<key>selection</key>
<string>#${config.colorScheme.palette.base02}</string>
<key>selectionForeground</key>
<string>#${config.colorScheme.palette.base05}</string>
<key>lineHighlight</key>
<string>#${config.colorScheme.palette.base01}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Comment</string>
<key>scope</key>
<string>comment</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base03}</string>
<key>fontStyle</key>
<string>italic</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>String</string>
<key>scope</key>
<string>string</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base0A}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Number</string>
<key>scope</key>
<string>constant.numeric</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base0E}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Keyword</string>
<key>scope</key>
<string>keyword</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base08}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Function</string>
<key>scope</key>
<string>entity.name.function</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base0B}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Type</string>
<key>scope</key>
<string>entity.name.type, storage.type</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base0D}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Variable</string>
<key>scope</key>
<string>variable</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base05}</string>
</dict>
</dict>
<dict>
<key>name</key>
<string>Constant</string>
<key>scope</key>
<string>constant</string>
<key>settings</key>
<dict>
<key>foreground</key>
<string>#${config.colorScheme.palette.base0E}</string>
</dict>
</dict>
</array>
</dict>
</plist>
'';
};
};
};
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
];
}

View File

@@ -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";
};
};
}

View File

@@ -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];
};
}

View File

@@ -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}";
};
};
};
};
};
}

View File

@@ -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}";
};
};
};
};
}

View File

@@ -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)

View File

@@ -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;
};
};
}

View File

@@ -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];
};
}

View File

@@ -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
];
};
}

View File

@@ -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";
};
};
};
};
}

View File

@@ -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
];
};
}

View File

@@ -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;
};
};
}

95
home/lib/default.nix Normal file
View File

@@ -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)} ]";
}
];
};
}

View File

@@ -1,17 +1,25 @@
{ # m3-aether — cloud VM.
# Context: server | Profiles: (none)
{lib, ...}: let
homeLib = import ../lib {inherit lib;};
in {
imports = [ imports = [
../common (homeLib.mkHomeConfig {
../features/cli profiles = [];
context = "server";
})
./home-server.nix ./home-server.nix
]; ];
features = { # Base CLI tools (new namespace)
cli = { base = {
shell = {
fish.enable = true; fish.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true; fzf.enable = true;
nitch.enable = true; nitch.enable = true;
secrets.enable = false;
starship.enable = true;
}; };
}; };
} }

View File

@@ -1,21 +1,88 @@
# m3-ares — TUXEDO laptop desktop workstation.
# Context: desktop | Profiles: coding, gaming, media
{ {
config, config,
lib, lib,
... ...
}: }: let
homeLib = import ../lib {inherit lib;};
in
with lib; { with lib; {
imports = [ imports = [
../common (homeLib.mkHomeConfig {
profiles = ["coding" "gaming" "media"];
context = "desktop";
})
./home.nix ./home.nix
../features/cli
../features/coding
../features/desktop
]; ];
config = mkMerge [ config = mkMerge [
{ {
# Base CLI tools (new namespace)
base = {
shell = {
fish.enable = true;
nushell.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true;
nitch.enable = true;
television.enable = true;
};
secrets.enable = true;
};
# 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 = { xdg = {
# TODO: better structure
enable = true; enable = true;
configFile."mimeapps.list".force = true; configFile."mimeapps.list".force = true;
mimeApps = { mimeApps = {
@@ -38,33 +105,10 @@ with lib; {
}; };
}; };
}; };
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 { # Host-specific Hyprland monitor and workspace layout
(mkIf config.desktop.wm.hyprland.enable {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
settings = { settings = {

View File

@@ -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 = [ imports = [
../common (homeLib.mkHomeConfig {
../features/cli profiles = ["coding"];
../features/coding/opencode.nix context = "server";
})
./home-server.nix ./home-server.nix
]; ];
coding.editors.neovim.enable = true;
features = { # Base CLI tools (new namespace)
cli = { base = {
shell = {
nushell.enable = true; nushell.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true; fzf.enable = true;
nitch.enable = true; nitch.enable = true;
secrets.enable = false;
starship.enable = true;
zellij.enable = true; zellij.enable = true;
}; };
}; };
# Coding environment
coding.editors.neovim.enable = true;
} }

View File

@@ -1,28 +1,74 @@
# m3-daedalus — portable laptop (standalone home-manager).
# Context: desktop | Profiles: coding, media
{ {
config, config,
lib, lib,
... ...
}: }: let
with lib; let homeLib = import ../lib {inherit lib;};
cfg = config.features.desktop.hyprland; in
in { with lib; {
imports = [ imports = [
../common (homeLib.mkHomeConfig {
profiles = ["coding" "media"];
context = "desktop";
})
./home.nix ./home.nix
../features/cli
../features/coding
../features/desktop
#./services/librechat.nix
]; ];
options.features.desktop.hyprland.enable =
mkEnableOption "enable Hyprland";
config = mkMerge [ config = mkMerge [
# Base configuration
{ {
# Base CLI tools (new namespace)
base = {
shell = {
fish.enable = true;
nushell.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true;
nitch.enable = true;
television.enable = true;
};
secrets.enable = true;
};
# 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 = { xdg = {
# TODO: better structure
enable = true; enable = true;
configFile."mimeapps.list".force = true; configFile."mimeapps.list".force = true;
mimeApps = { mimeApps = {
@@ -45,30 +91,10 @@ in {
}; };
}; };
}; };
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 { # Host-specific Hyprland layout — only applies when hyprland is enabled
(mkIf config.desktop.wm.hyprland.enable {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
settings = { settings = {

View File

@@ -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 = [ imports = [
../common (homeLib.mkHomeConfig {
../features/cli profiles = [];
context = "server";
})
./home-server.nix ./home-server.nix
]; ];
features = { # Base CLI tools (new namespace)
cli = { base = {
shell = {
fish.enable = true; fish.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true; fzf.enable = true;
nitch.enable = true; nitch.enable = true;
secrets.enable = false;
starship.enable = true;
}; };
}; };
} }

View File

@@ -1,17 +1,25 @@
{ # m3-hermes — secondary server.
# Context: server | Profiles: (none)
{lib, ...}: let
homeLib = import ../lib {inherit lib;};
in {
imports = [ imports = [
../common (homeLib.mkHomeConfig {
../features/cli profiles = [];
context = "server";
})
./home-server.nix ./home-server.nix
]; ];
features = { # Base CLI tools (new namespace)
cli = { base = {
shell = {
fish.enable = true; fish.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true; fzf.enable = true;
nitch.enable = true; nitch.enable = true;
secrets.enable = false;
starship.enable = true;
}; };
}; };
} }

View File

@@ -1,21 +1,86 @@
# m3-kratos — AMD desktop workstation.
# Context: desktop | Profiles: coding, gaming, media
{ {
config, config,
lib, lib,
... ...
}: }: let
homeLib = import ../lib {inherit lib;};
in
with lib; { with lib; {
imports = [ imports = [
../common (homeLib.mkHomeConfig {
profiles = ["coding" "gaming" "media"];
context = "desktop";
})
./home.nix ./home.nix
../features/cli
../features/coding
../features/desktop
]; ];
config = mkMerge [ config = mkMerge [
{ {
# Base CLI tools (new namespace)
base = {
shell = {
nushell.enable = true;
starship.enable = true;
};
cliTools = {
fzf.enable = true;
nitch.enable = true;
television.enable = true;
};
secrets.enable = true;
};
# 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;
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 = { xdg = {
# TODO: better structure
enable = true; enable = true;
configFile."mimeapps.list".force = true; configFile."mimeapps.list".force = true;
mimeApps = { mimeApps = {
@@ -38,32 +103,10 @@ with lib; {
}; };
}; };
}; };
features = {
cli = {
nushell.enable = true;
fzf.enable = true;
nitch.enable = true;
secrets.enable = true;
starship.enable = true;
television.enable = true;
};
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;
};
};
} }
(mkIf config.features.desktop.hyprland.enable { # Host-specific Hyprland monitor and workspace layout (dual 1440p monitors)
(mkIf config.desktop.wm.hyprland.enable {
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
settings = { settings = {
@@ -80,7 +123,6 @@ with lib; {
"6, monitor:DP-2" "6, monitor:DP-2"
"7, monitor:DP-2" "7, monitor:DP-2"
]; ];
windowrule = [ windowrule = [
"match:class dev.zed.Zed, workspace 1" "match:class dev.zed.Zed, workspace 1"
"match:class Msty, workspace 1" "match:class Msty, workspace 1"

View File

@@ -0,0 +1,8 @@
# Gaming profile aggregator — Steam platform, Gamescope session, and AMD GPU tools.
{...}: {
imports = [
./steam.nix
./gamescope.nix
./gpu.nix
];
}

View File

@@ -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];
};
}

View File

@@ -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
];
};
}

View File

@@ -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
];
};
}

View File

@@ -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
];
}

View File

@@ -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
];
};
}

View File

@@ -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
];
};
}

View File

@@ -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];
};
}

View File

@@ -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.
};
}

View File

@@ -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";
};
};
};
}

6
home/server/default.nix Normal file
View File

@@ -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.
}

View File

@@ -1,11 +1,15 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
imports = config,
[ (modulesPath + "/profiles/qemu-guest.nix") 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.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];

View File

@@ -1,7 +1,4 @@
{ {pkgs, ...}: {
pkgs,
...
}: {
services.postgresql = { services.postgresql = {
enable = true; enable = true;
package = pkgs.postgresql_17; package = pkgs.postgresql_17;

View File

@@ -11,8 +11,7 @@
"kestra_data:/app/storage" "kestra_data:/app/storage"
"/tmp/kestra-wd:/tmp/kestra-wd" "/tmp/kestra-wd:/tmp/kestra-wd"
]; ];
extraOptions = extraOptions = ["--add-host=postgres:10.89.0.1" "--ip=10.89.0.18" "--network=web"];
[ "--add-host=postgres:10.89.0.1" "--ip=10.89.0.18" "--network=web" ];
}; };
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
@@ -21,8 +20,7 @@
# Traefik configuration specific to littlelink # Traefik configuration specific to littlelink
services.traefik.dynamicConfigOptions.http = { services.traefik.dynamicConfigOptions.http = {
services.kestra.loadBalancer.servers = services.kestra.loadBalancer.servers = [{url = "http://localhost:3018/";}];
[{ url = "http://localhost:3018/"; }];
routers.kestra = { routers.kestra = {
rule = "Host(`k.m3ta.dev`)"; rule = "Host(`k.m3ta.dev`)";

View File

@@ -1,11 +1,15 @@
# Do not modify this file! It was generated by nixos-generate-config # Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
imports = config,
[ (modulesPath + "/profiles/qemu-guest.nix") 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.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];

View File

@@ -1,7 +1,13 @@
# Do not modify this file! It was generated by 'nixos-generate-config' # Do not modify this file! It was generated by 'nixos-generate-config'
# and may be overwritten by future invocations. Please make changes # and may be overwritten by future invocations. Please make changes
# to configuration.nix instead. # to configuration.nix instead.
{config, lib, pkgs, modulesPath, ...}: { {
config,
lib,
pkgs,
modulesPath,
...
}: {
imports = [ imports = [
(modulesPath + "/profiles/qemu-guest.nix") (modulesPath + "/profiles/qemu-guest.nix")
]; ];