stt, mem0, rofi-project-opener
This commit is contained in:
368
AGENTS.md
368
AGENTS.md
@@ -1,283 +1,157 @@
|
|||||||
# AGENTS.md - NixOS Configuration Repository
|
# NIXOS CONFIGURATION KNOWLEDGE BASE
|
||||||
|
|
||||||
**Generated:** 2025-12-29 | **Branch:** master | **Commit:** 460fc92
|
**Generated:** 2025-12-31 16:13:40 UTC
|
||||||
|
**Commit:** ebc8291
|
||||||
|
**Branch:** HEAD
|
||||||
|
|
||||||
Multi-host NixOS flake managing servers and workstations with home-manager integration.
|
## OVERVIEW
|
||||||
|
Personal NixOS configuration managing 6 hosts (4 servers, 2 desktops) using flakes, agenix secrets, and feature-based home-manager setup.
|
||||||
|
|
||||||
## Host Inventory
|
## STRUCTURE
|
||||||
|
|
||||||
| Host | Type | Purpose | Key Services |
|
|
||||||
|------|------|---------|--------------|
|
|
||||||
| m3-atlas | VPS | Main server | Traefik, containers (n8n, ghost, baserow, vaultwarden, paperless, gitea) |
|
|
||||||
| m3-helios | VPS | DNS/Dashboard | AdGuard Home, Homarr, Traefik |
|
|
||||||
| m3-ares | Workstation | Desktop | WireGuard VPN, Tailscale, sound, podman |
|
|
||||||
| m3-kratos | Workstation | Desktop | WireGuard VPN, Tailscale, Hyprland, gaming |
|
|
||||||
| m3-aether | VM | Cloud-init | Minimal config |
|
|
||||||
| m3-daedalus | - | Home-manager only | Desktop environment (no NixOS config) |
|
|
||||||
|
|
||||||
## Key Inputs
|
|
||||||
|
|
||||||
nixpkgs (unstable), nixpkgs-stable (25.05), home-manager, agenix, disko, nix-colors, m3ta-nixpkgs (private fork)
|
|
||||||
|
|
||||||
## Build/Rebuild Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# NixOS system rebuild
|
|
||||||
sudo nixos-rebuild switch --flake .#<hostname>
|
|
||||||
sudo nixos-rebuild switch --flake .#m3-atlas
|
|
||||||
|
|
||||||
# Home-manager rebuild
|
|
||||||
home-manager --flake . switch
|
|
||||||
home-manager --flake .#m3tam3re@m3-daedalus switch
|
|
||||||
|
|
||||||
# Flake operations
|
|
||||||
nix flake check # Validate flake
|
|
||||||
nix flake update # Update all inputs
|
|
||||||
nix flake lock --update-input <name> # Update single input
|
|
||||||
|
|
||||||
# Development shell
|
|
||||||
nix develop .#infraShell # OpenTofu + nixos-anywhere
|
|
||||||
|
|
||||||
# Format Nix files
|
|
||||||
alejandra . # Format all .nix files
|
|
||||||
alejandra <file.nix> # Format single file
|
|
||||||
```
|
```
|
||||||
|
./
|
||||||
## Testing
|
├── flake.nix # Main entry: host definitions, inputs, outputs
|
||||||
|
|
||||||
No formal test suite. Verification is done via:
|
|
||||||
```bash
|
|
||||||
nix flake check # Syntax and evaluation check
|
|
||||||
nix build .#nixosConfigurations.<host>.config.system.build.toplevel --dry-run
|
|
||||||
```
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── flake.nix # Flake definition with all hosts
|
|
||||||
├── secrets.nix # Agenix public key mappings
|
├── secrets.nix # Agenix public key mappings
|
||||||
├── home/
|
|
||||||
│ ├── common/ # Shared home-manager config (overlays, nix settings)
|
|
||||||
│ ├── features/ # Modular features
|
|
||||||
│ │ ├── cli/ # Shell tools (fish, nushell, starship, zellij)
|
|
||||||
│ │ ├── coding/ # Development tools
|
|
||||||
│ │ └── desktop/ # GUI apps, Hyprland, theming
|
|
||||||
│ └── m3tam3re/ # Per-host user configs
|
|
||||||
├── hosts/
|
├── hosts/
|
||||||
│ ├── common/ # Shared NixOS config
|
│ ├── common/ # Shared: base config, users, extraServices, ports
|
||||||
│ │ ├── extraServices/ # Toggle-able services (ollama, podman, flatpak)
|
│ ├── m3-atlas/ # Server: 20+ containerized services with Traefik
|
||||||
│ │ ├── users/ # User definitions
|
│ ├── m3-helios/ # Server: AdGuard, internal routing
|
||||||
│ │ └── ports.nix # Port allocations
|
│ ├── m3-ares/ # Desktop: NVIDIA GPU, Btrfs
|
||||||
│ └── m3-*/ # Host-specific configs
|
│ ├── m3-kratos/ # Desktop: AMD GPU, ZFS
|
||||||
│ ├── default.nix # Entry point (imports common + host modules)
|
│ └── m3-aether/ # Cloud VM
|
||||||
│ ├── configuration.nix # Core system config
|
├── home/
|
||||||
│ ├── hardware-configuration.nix
|
│ ├── common/ # Home-manager base config
|
||||||
│ ├── programs.nix # Host-specific programs
|
│ ├── features/ # Modular feature toggles (cli, desktop, coding)
|
||||||
│ ├── secrets.nix # Agenix secret declarations
|
│ └── m3tam3re/ # Per-host user configs
|
||||||
│ └── services/ # Service configurations
|
|
||||||
│ └── containers/ # OCI container definitions
|
|
||||||
├── modules/ # Custom NixOS/home-manager modules
|
├── modules/ # Custom NixOS/home-manager modules
|
||||||
├── overlays/ # Nixpkgs overlays (stable, locked, pinned, master)
|
├── overlays/ # Package overlays (stable, locked, pinned, master)
|
||||||
├── pkgs/ # Custom package definitions
|
├── pkgs/ # Custom package definitions
|
||||||
└── secrets/ # Encrypted .age files
|
└── secrets/ # Agenix encrypted .age files (19 secrets)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Code Style Guidelines
|
## WHERE TO LOOK
|
||||||
|
|
||||||
### Module Pattern
|
| Task | Location | Notes |
|
||||||
|
|------|----------|-------|
|
||||||
|
| Add new host | `flake.nix` + `hosts/<name>/` | Copy template from m3-atlas (server) or m3-ares (desktop) |
|
||||||
|
| Add service to m3-atlas | `hosts/m3-atlas/services/` | See containers/ for Podman + Traefik pattern |
|
||||||
|
| Configure desktop features | `home/features/desktop/` | Feature toggles with mkEnableOption |
|
||||||
|
| Add CLI tool | `home/features/cli/` | Fish + Nushell integration expected |
|
||||||
|
| Manage secrets | `secrets.nix` + `agenix -e` | SSH keys defined in secrets.nix |
|
||||||
|
| Define ports | `hosts/common/ports.nix` | Centralized port registry |
|
||||||
|
| Add user | `hosts/common/users/` | Shared across all hosts |
|
||||||
|
| Custom packages | `pkgs/default.nix` | Exposed via flake outputs |
|
||||||
|
|
||||||
Standard Nix module structure:
|
## CONVENTIONS
|
||||||
```nix
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
./submodule.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
# Configuration here
|
### Secrets (agenix)
|
||||||
}
|
- **Create**: `agenix -e secrets/<name>.age` after adding keys to `secrets.nix`
|
||||||
```
|
- **Reference**: `config.age.secrets.<name>.path` in service configs
|
||||||
|
- **Pattern**: Service env files use `environmentFiles = [config.age.secrets.<service>-env.path]`
|
||||||
|
|
||||||
### Formatting
|
### Service Organization
|
||||||
|
- **Native services**: `hosts/<host>/services/<service>.nix`
|
||||||
|
- **Containers**: `hosts/<host>/services/containers/<service>.nix`
|
||||||
|
- **Traefik integration**: All m3-atlas services include dynamic config for SSL + routing
|
||||||
|
- **Networking**: Containers use dedicated `web` network (10.89.0.0/24) with static IPs
|
||||||
|
|
||||||
- **Formatter**: Use `alejandra` (included in CLI packages)
|
### Port Management
|
||||||
- **Indentation**: 2 spaces
|
- **Registry**: All ports defined in `hosts/common/ports.nix`
|
||||||
- **Line length**: No strict limit, but keep readable
|
- **Access**: `config.m3ta.ports.get "service-name"`
|
||||||
- **Trailing commas**: Required in lists and attrsets
|
- **Convention**: Internal services use 3000-3020 range
|
||||||
- **Semicolons**: Required after each attribute
|
|
||||||
|
|
||||||
### Naming Conventions
|
### Home-Manager Features
|
||||||
|
- **Enable**: `features.<category>.<feature>.enable = true` in user config
|
||||||
|
- **Categories**: `cli`, `desktop`, `coding`
|
||||||
|
- **Pattern**: Features are opt-in modules with default.nix aggregators
|
||||||
|
|
||||||
| Type | Convention | Example |
|
### Multiple nixpkgs Inputs
|
||||||
|------|------------|---------|
|
- **stable**: 25.11 release
|
||||||
| Files | lowercase, hyphenated | `hardware-configuration.nix` |
|
- **locked/pinned**: Specific commits for compatibility
|
||||||
| Hosts | `m3-<name>` | `m3-atlas`, `m3-kratos` |
|
- **master**: Bleeding edge
|
||||||
| Options | camelCase path | `extraServices.ollama.enable` |
|
- **m3ta-nixpkgs**: Custom local overlay at `path:/home/m3tam3re/p/nix/nixpkgs`
|
||||||
| Feature flags | `features.<category>.<name>.enable` | `features.cli.nushell.enable` |
|
|
||||||
| Secrets | `<service>-env.age` or descriptive | `n8n-env.age`, `wg-DE.age` |
|
|
||||||
|
|
||||||
### Option Definitions
|
## COMMANDS
|
||||||
|
|
||||||
Use lib functions for custom options:
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.features.cli.myFeature;
|
|
||||||
in {
|
|
||||||
options.features.cli.myFeature.enable = mkEnableOption "enable myFeature";
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# Configuration when enabled
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Imports
|
|
||||||
|
|
||||||
- Import order: inputs/modules first, then local files
|
|
||||||
- Use relative paths: `./subdir` or `../common`
|
|
||||||
- Group related imports together
|
|
||||||
|
|
||||||
### Package Lists
|
|
||||||
|
|
||||||
```nix
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
package1
|
|
||||||
package2
|
|
||||||
# Commented packages for reference
|
|
||||||
# disabled-package
|
|
||||||
];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Secrets Management
|
|
||||||
|
|
||||||
Uses **agenix** for encrypted secrets.
|
|
||||||
|
|
||||||
### Adding a New Secret
|
|
||||||
|
|
||||||
1. Create the secret file:
|
|
||||||
```bash
|
```bash
|
||||||
agenix -e secrets/my-secret.age
|
# Build/deploy specific host
|
||||||
|
sudo nixos-rebuild switch --flake .#m3-ares
|
||||||
|
|
||||||
|
# Build/deploy current host
|
||||||
|
sudo nixos-rebuild switch --flake .#$(uname -n)
|
||||||
|
|
||||||
|
# Home-manager update
|
||||||
|
home-manager --flake . switch
|
||||||
|
|
||||||
|
# Update all flake inputs
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
# Add/edit secret
|
||||||
|
agenix -e secrets/<name>.age
|
||||||
|
|
||||||
|
# Infrastructure shell (OpenTofu)
|
||||||
|
nix develop .#infraShell
|
||||||
|
|
||||||
|
# Check configuration (no activation)
|
||||||
|
nixos-rebuild dry-build --flake .#<hostname>
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Register in `secrets.nix`:
|
## TRAEFIK PATTERNS (m3-atlas only)
|
||||||
|
|
||||||
|
### SSL Termination
|
||||||
|
- **Provider**: Godaddy DNS challenge
|
||||||
|
- **Cert storage**: `/var/lib/traefik/acme.json`
|
||||||
|
- **Config**: `hosts/m3-atlas/services/traefik.nix`
|
||||||
|
|
||||||
|
### Service Integration Template
|
||||||
```nix
|
```nix
|
||||||
"secrets/my-secret.age".publicKeys = systems ++ users;
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Declare in host's `secrets.nix`:
|
|
||||||
```nix
|
|
||||||
age.secrets.my-secret = {
|
|
||||||
file = ../../secrets/my-secret.age;
|
|
||||||
owner = "service-user"; # Optional
|
|
||||||
mode = "644"; # Optional
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Reference in config:
|
|
||||||
```nix
|
|
||||||
environmentFiles = [config.age.secrets.my-secret.path];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Container Services Pattern
|
|
||||||
|
|
||||||
OCI containers via podman:
|
|
||||||
```nix
|
|
||||||
{config, ...}: {
|
|
||||||
virtualisation.oci-containers.containers."service-name" = {
|
|
||||||
image = "registry/image:tag";
|
|
||||||
environmentFiles = [config.age.secrets.service-env.path];
|
|
||||||
ports = ["127.0.0.1:8080:8080"];
|
|
||||||
volumes = ["service_data:/data"];
|
|
||||||
extraOptions = ["--network=web"];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Traefik routing
|
|
||||||
services.traefik.dynamicConfigOptions.http = {
|
services.traefik.dynamicConfigOptions.http = {
|
||||||
services.service-name.loadBalancer.servers = [
|
services.<name>.loadBalancer.servers = [{ url = "http://127.0.0.1:<port>"; }];
|
||||||
{ url = "http://localhost:8080/"; }
|
routers.<name> = {
|
||||||
];
|
rule = "Host(`<subdomain>.m3ta.dev`)";
|
||||||
routers.service-name = {
|
service = "<name>";
|
||||||
rule = "Host(`service.domain.com`)";
|
|
||||||
tls.certResolver = "godaddy";
|
tls.certResolver = "godaddy";
|
||||||
service = "service-name";
|
|
||||||
entrypoints = "websecure";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Theming
|
### Container Pattern
|
||||||
|
- **Network**: `--network=web --ip=10.89.0.<sequential>`
|
||||||
|
- **Ports**: Bind localhost only (`127.0.0.1:<external>:<internal>`)
|
||||||
|
- **Database access**: `--add-host=mysql:10.89.0.1` (gateway IP)
|
||||||
|
|
||||||
Uses **nix-colors** with Dracula scheme:
|
## HOST ROLES
|
||||||
```nix
|
|
||||||
colorScheme = inputs.nix-colors.colorSchemes.dracula;
|
|
||||||
|
|
||||||
# Reference colors
|
| Host | Type | Hardware | Purpose |
|
||||||
"#${config.colorScheme.palette.base00}" # Background
|
|------|------|----------|---------|
|
||||||
"#${config.colorScheme.palette.base05}" # Foreground
|
| m3-atlas | Server | x86_64, disko | 20+ services, Traefik hub, PostgreSQL, MySQL |
|
||||||
```
|
| m3-helios | Server | x86_64, disko | AdGuard DNS, internal routing |
|
||||||
|
| m3-ares | Desktop | NVIDIA, Btrfs | Personal workstation, n8n, PostgreSQL |
|
||||||
|
| m3-kratos | Desktop | AMD, ZFS | Workstation, mem0, PostgreSQL |
|
||||||
|
| m3-aether | Cloud | QEMU | General purpose VM |
|
||||||
|
| m3-daedalus | Laptop | home-only | Portable (no full NixOS config) |
|
||||||
|
|
||||||
## Overlays
|
## ANTI-PATTERNS (THIS PROJECT)
|
||||||
|
|
||||||
Custom overlays in `overlays/default.nix`:
|
- **DON'T** add secrets to `secrets/` without updating `secrets.nix` public keys
|
||||||
- `stable-packages`: nixpkgs-stable as `pkgs.stable.*`
|
- **DON'T** hardcode ports - use `config.m3ta.ports.get` or add to registry
|
||||||
- `locked-packages`: Pinned nixpkgs as `pkgs.locked.*`
|
- **DON'T** create containers outside the `web` network on m3-atlas
|
||||||
- `master-packages`: nixpkgs-master as `pkgs.master.*`
|
- **DON'T** skip Traefik config for public-facing services on m3-atlas
|
||||||
|
- **DON'T** bypass extraServices flags - use `hosts/common/extraServices/` pattern
|
||||||
|
- **DON'T** commit unencrypted secrets or test with real credentials
|
||||||
|
|
||||||
Use when you need a specific package version:
|
## UNIQUE TO THIS CONFIG
|
||||||
```nix
|
|
||||||
home.packages = [ pkgs.stable.somePackage ];
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Pitfalls
|
- **Custom m3ta-nixpkgs**: Local overlay for unreleased/patched packages
|
||||||
|
- **extraServices abstraction**: Boolean flags to toggle Podman, Ollama, virtualisation per host
|
||||||
|
- **Mythological naming**: All hosts named after Greek mythology
|
||||||
|
- **Dual domain strategy**: New services on `m3ta.dev`, legacy redirects from `m3tam3re.com`
|
||||||
|
- **Per-host nixpkgs versions**: Different hosts can use different nixpkgs commits via specialArgs
|
||||||
|
- **Container IP registry**: Static IP assignments in 10.89.0.0/24 subnet for predictable networking
|
||||||
|
|
||||||
1. **Missing imports**: Ensure new files are imported in parent `default.nix`
|
## NOTES
|
||||||
2. **Secret paths**: Use `config.age.secrets.<name>.path`, not hardcoded paths
|
|
||||||
3. **Rebuild required**: Changes need `nixos-rebuild` or `home-manager switch`
|
|
||||||
4. **Overlay scope**: Overlays must be added to both `home/common` and `hosts/common`
|
|
||||||
5. **Port conflicts**: Check `hosts/common/ports.nix` before allocating new ports
|
|
||||||
|
|
||||||
## Commit Style
|
- m3-atlas is the service hub - most complex configuration
|
||||||
|
- Secrets require host SSH keys defined in `secrets.nix` before `agenix -e` works
|
||||||
Short, descriptive messages:
|
- Fish and Nushell both configured - choose per-user with shell aliases
|
||||||
- `flake update` - Dependency updates
|
- Color scheme (Dracula) applied via nix-colors across all visual tools
|
||||||
- `+package` - Adding new package
|
- See subdirectory AGENTS.md for deep dives on containers, desktop features, CLI tools
|
||||||
- `service-name: description` - Service changes
|
|
||||||
- `host: description` - Host-specific changes
|
|
||||||
|
|
||||||
## Container IP Registry (m3-atlas)
|
|
||||||
|
|
||||||
Network: `10.89.0.0/24`, Gateway: `10.89.0.1` (postgres host)
|
|
||||||
|
|
||||||
| Service | IP | Port |
|
|
||||||
|---------|-----|------|
|
|
||||||
| baserow | 10.89.0.4 | 3001 |
|
|
||||||
| ghost | 10.89.0.10 | 3002 |
|
|
||||||
| slash | 10.89.0.11 | 3010 |
|
|
||||||
| littlelink | 10.89.0.13 | 3004 |
|
|
||||||
| n8n | 10.89.0.14 | 5678 |
|
|
||||||
| restreamer | 10.89.0.15 | 3006 |
|
|
||||||
| kestra | 10.89.0.17 | 3018 |
|
|
||||||
| pangolin | 10.89.0.20 | 3020 |
|
|
||||||
|
|
||||||
**Next available IP**: 10.89.0.22
|
|
||||||
|
|
||||||
## Feature Flags
|
|
||||||
|
|
||||||
Home-manager features use `mkEnableOption` pattern:
|
|
||||||
- `features.cli.*` - Shell tools (nushell, fzf, nitch, starship, secrets)
|
|
||||||
- `features.desktop.*` - GUI apps (crypto, coding, gaming, hyprland, media, office, rofi, fonts, wayland)
|
|
||||||
- `extraServices.*` - NixOS services (ollama, podman, flatpak, virtualisation)
|
|
||||||
|
|
||||||
Enable in per-host configs: `features.cli.nushell.enable = true;`
|
|
||||||
|
|||||||
46
flake.lock
generated
46
flake.lock
generated
@@ -146,11 +146,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766682973,
|
"lastModified": 1766387499,
|
||||||
"narHash": "sha256-GKO35onS711ThCxwWcfuvbIBKXwriahGqs+WZuJ3v9E=",
|
"narHash": "sha256-AjK3/UKDzeXFeYNLVBaJ3+HLE9he1g5UrlNd4/BM3eA=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "91cdb0e2d574c64fae80d221f4bf09d5592e9ec2",
|
"rev": "527ad07e6625302b648ed3b28c34b62a79bd103e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -209,11 +209,11 @@
|
|||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766564648,
|
"lastModified": 1762493267,
|
||||||
"narHash": "sha256-xgMcrwKhFSQeSQN7ak0iUHNsnxaprEzuRYRo2ADeTtg=",
|
"narHash": "sha256-W/eYgKKVqCh7SJLHk6Asc4LvU3YXvGtlL29yBMGymz4=",
|
||||||
"owner": "Jas-SinghFSU",
|
"owner": "Jas-SinghFSU",
|
||||||
"repo": "HyprPanel",
|
"repo": "HyprPanel",
|
||||||
"rev": "17ecff630bece1ac81569e427088ee8b11322f36",
|
"rev": "f9a04192e8fb90a48e1756989f582dc0baec2351",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -227,11 +227,11 @@
|
|||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766478371,
|
"lastModified": 1767362052,
|
||||||
"narHash": "sha256-x9lJbQ0HuwpG17OColK0ueLYsZYz8/9+KBIVlZG18RU=",
|
"narHash": "sha256-NfrV9/JtD37WX7+H4UaFcTSnqmpSpr8f2Za+qo1duxM=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "d7d64634eef57179b1411b251496154c0c54578b",
|
"rev": "0b4c2efc8f4298168befc24d6a55cb732772caae",
|
||||||
"revCount": 11,
|
"revCount": 18,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://code.m3ta.dev/m3tam3re/nixpkgs"
|
"url": "https://code.m3ta.dev/m3tam3re/nixpkgs"
|
||||||
},
|
},
|
||||||
@@ -374,11 +374,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-master": {
|
"nixpkgs-master": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766753232,
|
"lastModified": 1766476350,
|
||||||
"narHash": "sha256-gUj5f8xuGUg7dT+BDlWyb6FnyD7f8n6UrFcSGzwLv/E=",
|
"narHash": "sha256-JbSaOKi9jBGu1KG+BANYiocKsc+EI8Qb4MUKgtXnaTE=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a2eef3d4a9e42d1bfb122c4ca9550544ec7ccab1",
|
"rev": "48c44c67646d5a8c7c168e1ded8adf6fd8f3831b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -390,16 +390,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766687554,
|
"lastModified": 1767047869,
|
||||||
"narHash": "sha256-DegN7KD/EtFSKXf2jvqL6lvev6GlfAAatYBcRC8goEo=",
|
"narHash": "sha256-tzYsEzXEVa7op1LTnrLSiPGrcCY6948iD0EcNLWcmzo=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "fd0ca39c92fdb4012ed8d60e1683c26fddadd136",
|
"rev": "89dbf01df72eb5ebe3b24a86334b12c27d68016a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-25.05",
|
"ref": "nixos-25.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -454,11 +454,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_5": {
|
"nixpkgs_5": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766651565,
|
"lastModified": 1766309749,
|
||||||
"narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=",
|
"narHash": "sha256-3xY8CZ4rSnQ0NqGhMKAy5vgC+2IVK0NoVEzDoOh4DA4=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539",
|
"rev": "a6531044f6d0bef691ea18d4d4ce44d0daa6e816",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -492,11 +492,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766741918,
|
"lastModified": 1766476441,
|
||||||
"narHash": "sha256-FOb58l2rT3ZxDY0px1lGFUNPhaSKRcGwH94pWGl3vzQ=",
|
"narHash": "sha256-IUN09o1u22yEv3YaLUq5BE9xvVNsqHRrINUTrZxxnwM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "f85ac5163eb68087550897c67542a0f478651782",
|
"rev": "1a2c4782c53dccd364e404fc0eec7fddee46d815",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -16,14 +16,14 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.05";
|
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11";
|
||||||
nixpkgs-45570c2.url = "github:nixos/nixpkgs/45570c299dc2b63c8c574c4cd77f0b92f7e2766e";
|
nixpkgs-45570c2.url = "github:nixos/nixpkgs/45570c299dc2b63c8c574c4cd77f0b92f7e2766e";
|
||||||
nixpkgs-locked.url = "github:nixos/nixpkgs/2744d988fa116fc6d46cdfa3d1c936d0abd7d121";
|
nixpkgs-locked.url = "github:nixos/nixpkgs/2744d988fa116fc6d46cdfa3d1c936d0abd7d121";
|
||||||
nixpkgs-9e58ed7.url = "github:nixos/nixpkgs/9e58ed7ba759d81c98f033b7f5eba21ca68f53b0";
|
nixpkgs-9e58ed7.url = "github:nixos/nixpkgs/9e58ed7ba759d81c98f033b7f5eba21ca68f53b0";
|
||||||
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
||||||
|
|
||||||
m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
|
m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
|
||||||
#m3ta-nixpkgs.url = "path:/home/m3tam3re/p/nix/nixpkgs";
|
# m3ta-nixpkgs.url = "path:/home/m3tam3re/p/NIX/nixpkgs";
|
||||||
#
|
#
|
||||||
nur = {
|
nur = {
|
||||||
url = "github:nix-community/NUR";
|
url = "github:nix-community/NUR";
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
# home/ - Home Manager Configurations
|
|
||||||
|
|
||||||
User-level configurations managed by home-manager.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
home/
|
|
||||||
├── common/ # Shared home-manager config
|
|
||||||
│ └── default.nix # Overlays, nix-colors, allowUnfree
|
|
||||||
├── features/ # Modular, toggle-able features
|
|
||||||
│ ├── cli/ # Shell tools (see features/AGENTS.md)
|
|
||||||
│ ├── coding/ # Dev tools
|
|
||||||
│ └── desktop/ # GUI, Hyprland, theming
|
|
||||||
└── m3tam3re/ # Per-host user configs
|
|
||||||
├── home.nix # Shared user config (git, ssh, packages)
|
|
||||||
└── m3-<host>.nix # Host-specific (imports features, monitor layouts)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Per-Host Config Pattern
|
|
||||||
|
|
||||||
Each `m3-<host>.nix`:
|
|
||||||
1. Imports `../common`, `./home.nix`, and needed `../features/*`
|
|
||||||
2. Enables specific features via `features.<category>.<name>.enable`
|
|
||||||
3. Overrides host-specific settings (monitors, default apps)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
imports = [../common ./home.nix ../features/cli ../features/desktop];
|
|
||||||
|
|
||||||
features.cli.nushell.enable = true;
|
|
||||||
features.desktop.hyprland.enable = true;
|
|
||||||
|
|
||||||
wayland.windowManager.hyprland.settings.monitor = ["DP-1,2560x1440,0x0,1"];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Theming
|
|
||||||
|
|
||||||
Uses nix-colors (Dracula scheme). Access colors:
|
|
||||||
```nix
|
|
||||||
"#${config.colorScheme.palette.base00}" # Background
|
|
||||||
"#${config.colorScheme.palette.base05}" # Foreground
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding New User Config
|
|
||||||
|
|
||||||
1. Create `m3tam3re/m3-<newhost>.nix`
|
|
||||||
2. Import needed features
|
|
||||||
3. Add to `flake.nix` homeConfigurations (standalone) or host's home-manager.users
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# features/ - Modular Home Manager Features
|
|
||||||
|
|
||||||
Toggle-able feature modules using `mkEnableOption` pattern.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
features/
|
|
||||||
├── cli/ # Shell & terminal tools
|
|
||||||
│ ├── default.nix # Always-on CLI tools (bat, eza, direnv, carapace)
|
|
||||||
│ ├── nushell.nix # features.cli.nushell.enable
|
|
||||||
│ ├── fzf.nix # features.cli.fzf.enable
|
|
||||||
│ ├── starship.nix # features.cli.starship.enable
|
|
||||||
│ ├── zellij.nix # Always-on zellij config
|
|
||||||
│ └── secrets.nix # features.cli.secrets.enable
|
|
||||||
├── coding/ # Dev tools
|
|
||||||
│ └── default.nix # features.coding.* (zed, neovim)
|
|
||||||
└── desktop/ # GUI applications
|
|
||||||
├── default.nix # Always-on (kitty, xdg, cursor)
|
|
||||||
├── hyprland.nix # features.desktop.hyprland.enable
|
|
||||||
├── gaming.nix # features.desktop.gaming.enable
|
|
||||||
├── media.nix # features.desktop.media.enable
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Creating a New Feature
|
|
||||||
|
|
||||||
1. Create `<category>/<feature>.nix`:
|
|
||||||
```nix
|
|
||||||
{config, lib, ...}:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.features.<category>.<feature>;
|
|
||||||
in {
|
|
||||||
options.features.<category>.<feature>.enable =
|
|
||||||
mkEnableOption "description";
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# Configuration when enabled
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Import in `<category>/default.nix`
|
|
||||||
3. Enable in user configs: `features.<category>.<feature>.enable = true;`
|
|
||||||
|
|
||||||
## Feature Categories
|
|
||||||
|
|
||||||
| Category | Purpose | Key features |
|
|
||||||
|----------|---------|--------------|
|
|
||||||
| cli | Shell tools | nushell, fzf, starship, nitch, secrets |
|
|
||||||
| coding | Development | (in default.nix, no sub-features yet) |
|
|
||||||
| desktop | GUI/WM | hyprland, gaming, media, office, crypto, fonts, rofi, wayland |
|
|
||||||
|
|
||||||
## Always-On vs Toggle-able
|
|
||||||
|
|
||||||
- **default.nix**: Configuration that applies when the category is imported (no enable flag)
|
|
||||||
- **<feature>.nix**: Must be explicitly enabled via `features.*.enable = true`
|
|
||||||
|
|
||||||
## Desktop Feature Details
|
|
||||||
|
|
||||||
- `hyprland.nix`: Window manager config, keybinds, window rules (host overrides monitors/workspaces)
|
|
||||||
- `gaming.nix`: Steam, gamemode, mangohud
|
|
||||||
- `media.nix`: mpv, obs-studio, spotify
|
|
||||||
- `wayland.nix`: Clipboard, screenshots, idle management
|
|
||||||
65
home/features/cli/AGENTS.md
Normal file
65
home/features/cli/AGENTS.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# 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
|
||||||
@@ -12,7 +12,12 @@
|
|||||||
./starship.nix
|
./starship.nix
|
||||||
./zellij.nix
|
./zellij.nix
|
||||||
];
|
];
|
||||||
|
cli.stt-ptt = {
|
||||||
|
enable = true;
|
||||||
|
whisperPackage = pkgs.whisper-cpp-vulkan;
|
||||||
|
model = "ggml-large-v3-turbo";
|
||||||
|
notifyTimeout = 2000;
|
||||||
|
};
|
||||||
programs.carapace = {
|
programs.carapace = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableFishIntegration = true;
|
enableFishIntegration = true;
|
||||||
@@ -192,6 +197,7 @@
|
|||||||
agenix-cli
|
agenix-cli
|
||||||
alejandra
|
alejandra
|
||||||
bc
|
bc
|
||||||
|
bun
|
||||||
claude-code
|
claude-code
|
||||||
comma
|
comma
|
||||||
coreutils
|
coreutils
|
||||||
@@ -209,6 +215,7 @@
|
|||||||
llm
|
llm
|
||||||
lf
|
lf
|
||||||
nix-index
|
nix-index
|
||||||
|
libnotify
|
||||||
nushellPlugins.skim
|
nushellPlugins.skim
|
||||||
progress
|
progress
|
||||||
ripgrep
|
ripgrep
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ in {
|
|||||||
$env.FZF_DEFAULT_COMMAND = "fd --type f --exclude .git --follow --hidden"
|
$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.FLAKE = $"($env.HOME)/p/nixos/nixos-config"
|
$env.FLAKE = $"($env.HOME)/p/nixos/nixos-config"
|
||||||
$env.PATH = ($env.PATH | split row (char esep) | prepend $"($env.HOME)/.cache/.bun/bin" | uniq)
|
$env.PATH = ($env.PATH | split row (char esep) | append "/home/m3tam3re/.cache/.bun/bin" | uniq)
|
||||||
source /run/agenix/${config.home.username}-secrets
|
source /run/agenix/${config.home.username}-secrets
|
||||||
'';
|
'';
|
||||||
configFile.text = ''
|
configFile.text = ''
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
{pkgs, ...}: {
|
{pkgs, ...}: {
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
bun
|
|
||||||
code2prompt
|
|
||||||
devpod
|
devpod
|
||||||
#devpod-desktop
|
#devpod-desktop
|
||||||
|
code2prompt
|
||||||
nur.repos.charmbracelet.crush
|
nur.repos.charmbracelet.crush
|
||||||
(python3.withPackages (ps:
|
(python3.withPackages (ps:
|
||||||
with ps; [
|
with ps; [
|
||||||
|
|||||||
79
home/features/desktop/AGENTS.md
Normal file
79
home/features/desktop/AGENTS.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# 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)
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
./rofi.nix
|
./rofi.nix
|
||||||
./theme.nix
|
./theme.nix
|
||||||
./wayland.nix
|
./wayland.nix
|
||||||
|
./webapps.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
xdg = {
|
xdg = {
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
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.sessionPath = ["\${XDG_BIN_HOME}" "\${HOME}/.cargo/bin" "$HOME/.npm-global/bin" "$HOME/.cache/.bun/bin"];
|
||||||
|
|
||||||
fonts.fontconfig.enable = true;
|
fonts.fontconfig.enable = true;
|
||||||
|
|
||||||
@@ -125,7 +126,7 @@
|
|||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
appimage-run
|
appimage-run
|
||||||
anytype
|
stable.anytype
|
||||||
# blueberry
|
# blueberry
|
||||||
bemoji
|
bemoji
|
||||||
brave
|
brave
|
||||||
@@ -165,7 +166,6 @@
|
|||||||
telegram-desktop
|
telegram-desktop
|
||||||
vivaldi
|
vivaldi
|
||||||
vivaldi-ffmpeg-codecs
|
vivaldi-ffmpeg-codecs
|
||||||
warp-terminal
|
|
||||||
# wl-clipboard
|
# wl-clipboard
|
||||||
# wlogout
|
# wlogout
|
||||||
# wtype
|
# wtype
|
||||||
|
|||||||
@@ -169,13 +169,13 @@ in {
|
|||||||
"$mainMod SHIFT, S, exec, uwsm app -- rofi -show emoji"
|
"$mainMod SHIFT, S, exec, uwsm app -- rofi -show emoji"
|
||||||
"$mainMod, P, exec, uwsm app -- rofi-pass"
|
"$mainMod, P, exec, uwsm app -- rofi-pass"
|
||||||
"$mainMod SHIFT, P, pseudo"
|
"$mainMod SHIFT, P, pseudo"
|
||||||
|
"$mainMod, R, exec, stt-ptt start"
|
||||||
"$mainMod, J, togglesplit"
|
"$mainMod, J, togglesplit"
|
||||||
"$mainMod, h, movefocus, l"
|
"$mainMod, h, movefocus, l"
|
||||||
"$mainMod, l, movefocus, r"
|
"$mainMod, l, movefocus, r"
|
||||||
"$mainMod, k, movefocus, u"
|
"$mainMod, k, movefocus, u"
|
||||||
"$mainMod, j, movefocus, d"
|
"$mainMod, j, movefocus, d"
|
||||||
"$mainMod, 1, workspace, 1"
|
"$mainMod, 1, workspace, 1"
|
||||||
|
|
||||||
"$mainMod, 2, workspace, 2"
|
"$mainMod, 2, workspace, 2"
|
||||||
"$mainMod, 3, workspace, 3"
|
"$mainMod, 3, workspace, 3"
|
||||||
"$mainMod, 4, workspace, 4"
|
"$mainMod, 4, workspace, 4"
|
||||||
@@ -198,7 +198,9 @@ 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 = [
|
||||||
|
"$mainMod, R, exec, stt-ptt stop"
|
||||||
|
];
|
||||||
bindm = [
|
bindm = [
|
||||||
"$mainMod, mouse:272, movewindow"
|
"$mainMod, mouse:272, movewindow"
|
||||||
"$mainMod, mouse:273, resizewindow"
|
"$mainMod, mouse:273, resizewindow"
|
||||||
|
|||||||
@@ -179,5 +179,13 @@ in {
|
|||||||
}
|
}
|
||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
|
cli.rofi-project-opener = {
|
||||||
|
enable = true;
|
||||||
|
projectDirs = [
|
||||||
|
"$HOME/p/NIX"
|
||||||
|
];
|
||||||
|
terminal = pkgs.kitty;
|
||||||
|
terminalCommand = "opencode";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
icons = {
|
||||||
|
teams = pkgs.fetchurl {
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/microsoft-teams.svg";
|
||||||
|
sha256 = "sha256-Pr9QS8nnXJq97r4/G3c6JXi34zxHl0ps9gcyI8cN/s8=";
|
||||||
|
};
|
||||||
|
outlook = pkgs.fetchurl {
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/microsoft-outlook.svg";
|
||||||
|
sha256 = "sha256-3u8t5QNHFZvrAegxBiGicO4PjtMWhEaQSCv7MSSfLLc=";
|
||||||
|
};
|
||||||
|
opencode = pkgs.fetchurl {
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/opencode-dark.svg";
|
||||||
|
sha256 = "1lms4f8habamvdh2qqqz9psx4py9wx23mmlkkds44pvrbq3bkj3n";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
xdg.desktopEntries = {
|
||||||
|
teams = {
|
||||||
|
name = "Microsoft Teams";
|
||||||
|
exec = "launch-webapp https://teams.microsoft.com";
|
||||||
|
comment = "Open Microsoft Teams as a Desktop App";
|
||||||
|
categories = ["Application" "Network" "Chat"];
|
||||||
|
terminal = false;
|
||||||
|
icon = icons.teams;
|
||||||
|
};
|
||||||
|
outlook = {
|
||||||
|
name = "Microsoft Outlook";
|
||||||
|
exec = "launch-webapp https://outlook.office.com/mail/";
|
||||||
|
comment = "Open Microsoft Outlook as a Desktop App";
|
||||||
|
categories = ["Application" "Network"];
|
||||||
|
terminal = false;
|
||||||
|
icon = icons.outlook;
|
||||||
|
};
|
||||||
|
basecamp = {
|
||||||
|
name = "Basecamp";
|
||||||
|
exec = "launch-webapp https://3.basecamp.com/5996442/";
|
||||||
|
comment = "Open Basecamp as a Desktop App";
|
||||||
|
categories = ["Application" "Network"];
|
||||||
|
terminal = false;
|
||||||
|
icon = "/home/sascha.koenig/.local/share/icons/basecamp-logo.png";
|
||||||
|
};
|
||||||
|
opencode = {
|
||||||
|
name = "Opencode";
|
||||||
|
exec = "rofi-project-opener";
|
||||||
|
comment = "Open Opencode Terminal App";
|
||||||
|
categories = ["Application" "Development"];
|
||||||
|
terminal = false;
|
||||||
|
icon = icons.opencode;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
# hosts/ - NixOS Host Configurations
|
|
||||||
|
|
||||||
Host-specific NixOS system configurations. Each `m3-*` directory is a complete host.
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
hosts/
|
|
||||||
├── common/ # Shared by ALL hosts
|
|
||||||
│ ├── extraServices/ # Toggle-able services (ollama, podman, flatpak)
|
|
||||||
│ ├── users/ # User definitions
|
|
||||||
│ ├── ports.nix # Central port registry
|
|
||||||
│ └── default.nix # Overlays, nix settings, home-manager integration
|
|
||||||
└── m3-*/ # Per-host configurations
|
|
||||||
├── default.nix # Entry point (imports common + enables extraServices)
|
|
||||||
├── configuration.nix # Core system (boot, networking, stateVersion)
|
|
||||||
├── hardware-configuration.nix
|
|
||||||
├── programs.nix # Host-specific packages
|
|
||||||
├── secrets.nix # Agenix secret declarations
|
|
||||||
└── services/ # Service configs
|
|
||||||
└── containers/ # OCI container definitions (m3-atlas only has many)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding a New Host
|
|
||||||
|
|
||||||
1. Create `hosts/m3-<name>/` with required files
|
|
||||||
2. Add to `flake.nix` nixosConfigurations
|
|
||||||
3. Create matching `home/m3tam3re/m3-<name>.nix`
|
|
||||||
|
|
||||||
## Host Quick Reference
|
|
||||||
|
|
||||||
| Host | extraServices | Has disko | Key services/ files |
|
|
||||||
|------|---------------|-----------|---------------------|
|
|
||||||
| m3-atlas | podman | Yes | traefik, postgres, gitea, containers/* |
|
|
||||||
| m3-helios | - | Yes | adguard, traefik, containers/homarr |
|
|
||||||
| m3-ares | podman | No | wireguard, tailscale, sound |
|
|
||||||
| m3-kratos | podman, ollama | No | wireguard, tailscale, sound |
|
|
||||||
| m3-aether | - | Yes | cloud-init (minimal) |
|
|
||||||
|
|
||||||
## extraServices Pattern
|
|
||||||
|
|
||||||
Enable in host's `default.nix`:
|
|
||||||
```nix
|
|
||||||
extraServices = {
|
|
||||||
podman.enable = true;
|
|
||||||
ollama.enable = true;
|
|
||||||
flatpak.enable = false;
|
|
||||||
virtualisation.enable = false;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Port Allocation
|
|
||||||
|
|
||||||
ALWAYS check `common/ports.nix` before adding new services. Register new ports there.
|
|
||||||
|
|
||||||
## Secrets Declaration
|
|
||||||
|
|
||||||
Each host's `secrets.nix` declares only secrets it needs:
|
|
||||||
```nix
|
|
||||||
age.secrets.service-name = {
|
|
||||||
file = ../../secrets/service-name.age;
|
|
||||||
owner = "optional-user";
|
|
||||||
};
|
|
||||||
```
|
|
||||||
76
hosts/common/AGENTS.md
Normal file
76
hosts/common/AGENTS.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# COMMON HOST CONFIGURATION
|
||||||
|
|
||||||
|
**Shared base configuration and abstractions for all hosts**
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
Common imports, overlays, and custom patterns (extraServices, ports) used across 6 hosts.
|
||||||
|
|
||||||
|
## STRUCTURE
|
||||||
|
```
|
||||||
|
common/
|
||||||
|
├── default.nix # Base imports, overlays, nix settings
|
||||||
|
├── ports.nix # Centralized port registry
|
||||||
|
├── extraServices/ # Optional service modules
|
||||||
|
│ ├── default.nix
|
||||||
|
│ ├── flatpak.nix
|
||||||
|
│ ├── ollama.nix
|
||||||
|
│ ├── podman.nix
|
||||||
|
│ └── virtualisation.nix
|
||||||
|
└── users/
|
||||||
|
├── default.nix
|
||||||
|
└── m3tam3re.nix # Primary user definition
|
||||||
|
```
|
||||||
|
|
||||||
|
## WHERE TO LOOK
|
||||||
|
|
||||||
|
| Task | Location | Notes |
|
||||||
|
|------|----------|-------|
|
||||||
|
| Add port definition | ports.nix | Use config.m3ta.ports.get |
|
||||||
|
| Enable optional service | Host config extraServices | Boolean flags |
|
||||||
|
| Modify overlays | default.nix lines 27-36 | 5 overlay sources |
|
||||||
|
| Add new user | users/ | Shared across all hosts |
|
||||||
|
|
||||||
|
## CONVENTIONS
|
||||||
|
|
||||||
|
### Port Registry Pattern
|
||||||
|
```nix
|
||||||
|
# Define in ports.nix
|
||||||
|
definitions = {
|
||||||
|
myservice = 3099;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Access in host config
|
||||||
|
config.m3ta.ports.get "myservice" # Returns 3099
|
||||||
|
```
|
||||||
|
|
||||||
|
### extraServices Abstraction
|
||||||
|
Host configs enable via boolean:
|
||||||
|
```nix
|
||||||
|
extraServices = {
|
||||||
|
podman.enable = true; # Container runtime
|
||||||
|
ollama.enable = true; # LLM inference
|
||||||
|
flatpak.enable = false; # Flatpak apps
|
||||||
|
virtualisation.enable = true; # QEMU/KVM
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Overlay Precedence (bottom overrides top)
|
||||||
|
1. stable-packages (nixpkgs-stable)
|
||||||
|
2. locked-packages (nixpkgs-locked)
|
||||||
|
3. pinned-packages (nixpkgs-45570c2, nixpkgs-9e58ed7)
|
||||||
|
4. master-packages (nixpkgs-master)
|
||||||
|
5. m3ta-nixpkgs (local custom overlay)
|
||||||
|
|
||||||
|
## ANTI-PATTERNS
|
||||||
|
|
||||||
|
- **DON'T** add host-specific logic to common/ - belongs in hosts/<name>/
|
||||||
|
- **DON'T** bypass port registry - hardcoded ports break consistency
|
||||||
|
- **DON'T** modify user shell globally - set per-user if needed
|
||||||
|
|
||||||
|
## NOTES
|
||||||
|
|
||||||
|
- Nix GC runs weekly, keeps 30 days
|
||||||
|
- Trusted users: root, m3tam3re
|
||||||
|
- Default shell: Nushell (set line 77)
|
||||||
|
- Home-manager integrated at common level, not per-host
|
||||||
|
- TODO on line 69: ports should only return actually used ports
|
||||||
@@ -33,7 +33,6 @@
|
|||||||
userServices = true;
|
userServices = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
displayManager.gdm.enable = true;
|
|
||||||
};
|
};
|
||||||
systemd.sleep.extraConfig = ''
|
systemd.sleep.extraConfig = ''
|
||||||
AllowSuspend=no
|
AllowSuspend=no
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
# services/ - m3-atlas Service Configurations
|
|
||||||
|
|
||||||
Main server services including Traefik reverse proxy and containerized apps.
|
|
||||||
|
|
||||||
## Container Network
|
|
||||||
|
|
||||||
- **Network**: `web` (podman network)
|
|
||||||
- **Subnet**: `10.89.0.0/24`
|
|
||||||
- **Gateway/Postgres**: `10.89.0.1`
|
|
||||||
- **DNS Challenge**: GoDaddy via Traefik
|
|
||||||
|
|
||||||
## Adding a New Container
|
|
||||||
|
|
||||||
1. Pick next available IP from registry (currently: `10.89.0.22`)
|
|
||||||
2. Register port in `hosts/common/ports.nix`
|
|
||||||
3. Create `containers/<service>.nix`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{config, ...}: {
|
|
||||||
virtualisation.oci-containers.containers."service" = {
|
|
||||||
image = "registry/image:tag";
|
|
||||||
environmentFiles = [config.age.secrets.service-env.path];
|
|
||||||
ports = ["127.0.0.1:PORT:PORT"];
|
|
||||||
volumes = ["service_data:/data"];
|
|
||||||
extraOptions = [
|
|
||||||
"--add-host=postgres:10.89.0.1"
|
|
||||||
"--ip=10.89.0.XX"
|
|
||||||
"--network=web"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.traefik.dynamicConfigOptions.http = {
|
|
||||||
services.service.loadBalancer.servers = [{ url = "http://localhost:PORT/"; }];
|
|
||||||
routers.service = {
|
|
||||||
rule = "Host(`service.domain.com`)";
|
|
||||||
tls.certResolver = "godaddy";
|
|
||||||
service = "service";
|
|
||||||
entrypoints = "websecure";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Import in `containers/default.nix`
|
|
||||||
5. Add secret to `secrets.nix` and root `secrets.nix`
|
|
||||||
6. Update IP registry in root AGENTS.md
|
|
||||||
|
|
||||||
## Service Files (non-container)
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| traefik.nix | Reverse proxy, TLS, entrypoints |
|
|
||||||
| postgres.nix | Native PostgreSQL for containers |
|
|
||||||
| tailscale.nix | Mesh VPN |
|
|
||||||
| gitea.nix | Native Gitea (not containerized) |
|
|
||||||
| minio.nix | S3-compatible storage |
|
|
||||||
|
|
||||||
## Traefik Patterns
|
|
||||||
|
|
||||||
- HTTP redirect to HTTPS: automatic via `web` entrypoint
|
|
||||||
- TLS: `certResolver = "godaddy"` (DNS challenge)
|
|
||||||
- Auth middleware: `middlewares = ["auth"]` (basic auth)
|
|
||||||
- Domain redirects: See `traefik.nix` middlewares
|
|
||||||
85
hosts/m3-atlas/services/containers/AGENTS.md
Normal file
85
hosts/m3-atlas/services/containers/AGENTS.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# CONTAINER SERVICES (m3-atlas)
|
||||||
|
|
||||||
|
**Container orchestration with Podman + Traefik reverse proxy**
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
11 containerized services on dedicated `web` network (10.89.0.0/24) with Traefik SSL termination.
|
||||||
|
|
||||||
|
## STRUCTURE
|
||||||
|
```
|
||||||
|
containers/
|
||||||
|
├── default.nix # Network setup + service imports
|
||||||
|
├── baserow.nix # 10.89.0.10 - No-code database
|
||||||
|
├── ghost.nix # 10.89.0.11 - Blog platform
|
||||||
|
├── kestra.nix # 10.89.0.12 - Workflow orchestration
|
||||||
|
├── littlelink.nix # 10.89.0.13 - Link aggregator
|
||||||
|
├── matomo.nix # 10.89.0.14 - Analytics
|
||||||
|
├── restreamer.nix # 10.89.0.15 - Video streaming
|
||||||
|
├── slash.nix # 10.89.0.16 - Link shortener
|
||||||
|
└── slash-nemoti.nix # 10.89.0.17 - Personal link shortener
|
||||||
|
```
|
||||||
|
|
||||||
|
## WHERE TO LOOK
|
||||||
|
|
||||||
|
| Task | Action | Notes |
|
||||||
|
|------|--------|-------|
|
||||||
|
| Add container | Copy existing .nix, increment IP | Must update default.nix imports |
|
||||||
|
| Fix networking | Check IP conflicts in 10.89.0.0/24 | Gateway always 10.89.0.1 |
|
||||||
|
| Debug Traefik | Check router rules in service file | Domain must match DNS |
|
||||||
|
| Access database | Use `--add-host=mysql:10.89.0.1` | Gateway IP for host services |
|
||||||
|
|
||||||
|
## CONVENTIONS
|
||||||
|
|
||||||
|
### Container Definition Template
|
||||||
|
```nix
|
||||||
|
virtualisation.oci-containers.containers.<name> = {
|
||||||
|
image = "registry/image:tag";
|
||||||
|
ports = ["127.0.0.1:<external>:<internal>"];
|
||||||
|
volumes = ["/var/lib/<service>:/data"];
|
||||||
|
environmentFiles = [config.age.secrets.<name>-env.path];
|
||||||
|
extraOptions = [
|
||||||
|
"--network=web"
|
||||||
|
"--ip=10.89.0.<sequential>"
|
||||||
|
"--add-host=mysql:10.89.0.1" # If DB needed
|
||||||
|
];
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Traefik Integration
|
||||||
|
```nix
|
||||||
|
services.traefik.dynamicConfigOptions.http = {
|
||||||
|
services.<name>.loadBalancer.servers = [{
|
||||||
|
url = "http://127.0.0.1:<port>";
|
||||||
|
}];
|
||||||
|
routers.<name> = {
|
||||||
|
rule = "Host(`<subdomain>.m3ta.dev`)";
|
||||||
|
service = "<name>";
|
||||||
|
tls.certResolver = "godaddy";
|
||||||
|
};
|
||||||
|
# Legacy redirect (if needed)
|
||||||
|
routers.<name>-old = {
|
||||||
|
rule = "Host(`<subdomain>.m3tam3re.com`)";
|
||||||
|
service = "<name>";
|
||||||
|
middlewares = ["redirect-m3ta"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### IP Allocation
|
||||||
|
- **10.89.0.1**: Gateway (host)
|
||||||
|
- **10.89.0.10-17**: Assigned containers
|
||||||
|
- **10.89.0.18+**: Available for new services
|
||||||
|
|
||||||
|
## ANTI-PATTERNS
|
||||||
|
|
||||||
|
- **DON'T** expose ports publicly - bind to 127.0.0.1 only
|
||||||
|
- **DON'T** skip static IP assignment - routing breaks without it
|
||||||
|
- **DON'T** hardcode secrets - use age-encrypted env files
|
||||||
|
- **DON'T** forget to add imports to default.nix
|
||||||
|
|
||||||
|
## NOTES
|
||||||
|
|
||||||
|
- Network created via activation script in default.nix
|
||||||
|
- All services behind Traefik - no direct external access
|
||||||
|
- MySQL/PostgreSQL run on host, accessed via gateway IP
|
||||||
|
- Secrets pattern: `<service>-env.age` with environment variables
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./containers
|
./containers
|
||||||
|
./mem0.nix
|
||||||
./n8n.nix
|
./n8n.nix
|
||||||
./postgres.nix
|
./postgres.nix
|
||||||
./sound.nix
|
./sound.nix
|
||||||
|
|||||||
23
hosts/m3-kratos/services/mem0.nix
Normal file
23
hosts/m3-kratos/services/mem0.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
m3ta.mem0 = {
|
||||||
|
enable = true;
|
||||||
|
port = 8000;
|
||||||
|
host = "127.0.0.1";
|
||||||
|
|
||||||
|
# LLM Configuration
|
||||||
|
llm = {
|
||||||
|
provider = "openai";
|
||||||
|
apiKeyFile = "/var/lib/mem0/openai-api-key-1"; # Use agenix or sops-nix
|
||||||
|
};
|
||||||
|
|
||||||
|
# Vector Storage Configuration
|
||||||
|
vectorStore = {
|
||||||
|
provider = "qdrant"; # or "chroma", "pinecone", etc.
|
||||||
|
config = {
|
||||||
|
host = "localhost";
|
||||||
|
port = 6333;
|
||||||
|
collection_name = "mem0_alice";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user