Nix-Vibe public snapshot (squashed history)

This commit is contained in:
2026-09-19 13:56:12 +01:00
commit aee8fb1e9b
119 changed files with 18895 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
---
name: flake-update
description: 'Safely update flake inputs: ensure a clean committed/pushed working tree, run nix flake update, then dry-build EVERY host before committing flake.lock. Use when the user asks to update the flake, refresh flake.lock, bump inputs, or upgrade nixpkgs/dependencies.'
---
# Flake Update
## When to Use
- When the user asks to "update the flake", "bump inputs", "refresh flake.lock", or "update nixpkgs"
- Before a planned fleet-wide input upgrade
## Procedure
### 1. Clean Working Tree (MANDATORY)
Never run `nix flake update` with uncommitted changes — mixing unrelated edits with a lockfile bump makes rollback painful.
```bash
git status
```
- If there are uncommitted changes: validate and commit them first (follow the **nix-flake-rebuild** skill: stage, `nixpkgs-fmt .`, `nix flake check`, dry-build affected hosts, commit).
- Then push everything to the remote:
```bash
git push
```
Only proceed when `git status` is clean and the branch is fully pushed.
### 2. Update Inputs
```bash
# All inputs
nix flake update
# OR a single input, if the user asked for one
nix flake update <input-name>
```
### 3. Flake Check
```bash
nix flake check
```
Fix any evaluation errors before building. Input bumps often surface deprecated/renamed NixOS and Home Manager options — check warnings and refer to release notes for replacements.
### 4. Dry-Build EVERY Host
An input update affects the whole fleet — dry-build every host, no exceptions. Generate the host list dynamically from the flake so new hosts are never missed:
```bash
for host in $(nix eval .#nixosConfigurations --apply 'attrs: builtins.concatStringsSep " " (builtins.attrNames attrs)' --raw); do
echo "=== $host ==="
nixos-rebuild dry-build --flake .#$host || break
done
```
If any host fails, do NOT commit. Either fix the breakage or roll back (see below).
### 5. Commit & Push Lockfile (only if ALL hosts pass)
```bash
git add flake.lock
git commit -m "flake: update inputs"
git push
```
## Rollback
Because step 1 guaranteed a clean, pushed tree, the previous lockfile is always recoverable:
```bash
git restore --source=HEAD~1 flake.lock
```
Or check out an older known-good lockfile from history.
## Notes
- This skill only **validates** the update. Actually applying it (`nixos-rebuild switch`) is a separate, per-host step.
- Review the `git diff flake.lock` before committing if the user wants to know which inputs moved.
+90
View File
@@ -0,0 +1,90 @@
---
name: nix-flake-rebuild
description: 'Validate Nix Flake changes end-to-end: stage, check, dry-build, and commit. Use after ANY change to .nix files, flake inputs, or module imports. Use when the user asks to apply, test, validate, rebuild, or commit NixOS config changes.'
argument-hint: '[hostname]'
---
# Nix Flake Rebuild Validation
## When to Use
- After ANY modification to `.nix` files, `flake.nix`, or module imports
- Before applying configs with `nixos-rebuild switch`
- When the user asks to "test", "validate", "rebuild", or "apply" changes
- After adding new files, modules, or hosts
## Critical Pre-Check: Git Staging
Nix flakes ONLY see Git-tracked files. If you created new files or directories, **you must stage them first**:
```bash
git add <new-file> <new-directory/>
```
Failure to do this will cause `nix flake check` to fail with confusing "file not found" errors.
## Procedure
### 1. Sync Documentation (if needed)
If software was added/removed or a host role changed, update the software inventory table and host overview in `README.md`.
### 2. Stage ALL Changes
```bash
git add -A
```
This ensures flake evaluation can see every file.
### 3. Format Code
```bash
nixpkgs-fmt .
```
### 4. Run Flake Check
```bash
nix flake check
```
Fix any errors before proceeding. Common issues:
- Missing `git add` on new files
- Deprecated NixOS/Home Manager options
- Syntax errors in `.nix` files
### 5. Dry-Build for Affected Hosts
```bash
nixos-rebuild dry-build --flake .#<hostname>
```
Run for EACH host affected by the changes. If unsure which hosts are affected, run for all. Generate the host list dynamically from the flake so new hosts are never missed:
```bash
for host in $(nix eval .#nixosConfigurations --apply 'attrs: builtins.concatStringsSep " " (builtins.attrNames attrs)' --raw); do
echo "=== $host ==="
nixos-rebuild dry-build --flake .#$host || break
done
```
### 6. Commit (only if ALL checks pass)
```bash
git commit -m "descriptive message"
```
Do NOT commit if `nix flake check` or any dry-build failed.
## Host Reference
> Informational only — the dry-build loop above generates the host list dynamically and is authoritative. Keep this table roughly in sync when adding hosts (used to check which overlay a host gets).
| Host | Type | Overlay |
|------|------|---------|
| `x1carbon` | Desktop/laptop | Full (`overlays`: CUDA/NDI/stable) |
| `caitlin-x1` | Desktop/laptop | `desktopOverlays` |
| `x470` | Desktop/laptop | `desktopOverlays` |
| `mary-x270` | Desktop | `desktopOverlays` |
| `richmond-server` | Server | `serverOverlays` |
| `homeserver-1` | Server | `serverOverlays` |
| `mcf-server` | Server | `serverOverlays` |
| `mcf-stream` | Desktop/laptop | `desktopOverlays` |
| `hp-laptop` | Desktop/laptop | `desktopOverlays` |
## Post-Validation
After a successful commit, to actually apply:
```bash
# Local
sudo nixos-rebuild switch --flake .#<hostname>
# Remote
nixos-rebuild switch --target-host <user@host> --flake .#<hostname> --use-remote-sudo
```
+132
View File
@@ -0,0 +1,132 @@
---
name: nix-module
description: 'Create or update a NixOS or Home Manager module following Nix-Vibe conventions. Use when adding a new service, desktop app, hardware support, or shared configuration module. Use when the user asks to add a package, service, or application module.'
argument-hint: '<module-name> [service|desktop|hardware|core]'
---
# Nix Module Creation
## When to Use
- Adding a new service (e.g., a new containerized app, daemon, or web service)
- Adding a new desktop application module
- Adding hardware support (e.g., new device driver, firmware)
- Creating a new shared core module
- The user asks to "add support for X" or "create a module for X"
## Module Pattern
All service/feature modules MUST follow this pattern:
```nix
{ config, pkgs, lib, ... }:
{
options.services.<name> = {
enable = lib.mkEnableOption "description of the service";
# Additional options as needed
};
config = lib.mkIf config.services.<name>.enable {
# Configuration here
};
}
```
Reference implementation: [modules/services/immich.nix](../../modules/services/immich.nix)
## Procedure
### 1. Determine Module Type
| Type | Directory | Example |
|------|-----------|---------|
| Service (daemon, container, webapp) | `modules/services/` | immich, jellyfin, ntfy |
| Desktop app | `modules/desktop/apps/` | soundux, opencode, freeshow |
| Desktop environment | `modules/desktop/` | gnome.nix, gui.nix |
| Hardware support | `modules/hardware/` | fingerprint.nix |
| Core system config | `modules/core/` | common.nix, settings.nix, fonts.nix |
### 2. Create the Module File
#### Service Module Template
```nix
{ config, pkgs, lib, ... }:
{
options.services.<service-name> = {
enable = lib.mkEnableOption "<Service Description>";
port = lib.mkOption {
type = lib.types.port;
default = <default-port>;
description = "Port for <service>";
};
# Add data directories, user config, etc. as needed
};
config = lib.mkIf config.services.<service-name>.enable {
# Service-specific configuration
# For stateful services, ensure data directories exist
systemd.tmpfiles.rules = [
"d /var/lib/<service> 0700 <user> <group> -"
];
# Open firewall if needed
networking.firewall.allowedTCPPorts = [ config.services.<service-name>.port ];
};
}
```
#### Desktop App Module Template
```nix
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
<package-name>
];
}
```
### 3. Register in Host Configuration
Import the module in the target host's `configuration.nix`:
```nix
imports = [
# ...existing imports...
../../modules/services/<module-name>.nix
];
```
Then enable it:
```nix
services.<service-name>.enable = true;
```
### 4. Update README.md
Add the new software to the Software Inventory table with the appropriate host columns.
### 5. Validate
Run the full validation workflow. See [nix-flake-rebuild](../nix-flake-rebuild/SKILL.md).
## Key Conventions
### Secrets
Never hardcode secrets. Use SOPS:
```nix
sops.secrets."<host>/<secret-name>" = {
owner = "<user>";
group = "users";
mode = "0440";
};
```
See [docs/sops-secrets.md](../../docs/sops-secrets.md) for details.
### Overlay Awareness
- If a package needs NVIDIA/CUDA or NDI, it should only be added to `x1carbon` (the only host using the full `overlays` set)
- Desktops/laptops use `desktopOverlays` (`stable` without CUDA); servers use `serverOverlays`
### Module Composition
- Core modules (`modules/core/common.nix`) apply to ALL hosts
- Desktop modules only apply to GUI hosts
- Service modules are imported per-host as needed
+246
View File
@@ -0,0 +1,246 @@
---
name: nix-new-host
description: 'Scaffold a new NixOS host in this flake: create host directory, config files, wire into flake.nix, and set up Home Manager users. Use when adding a new machine (desktop, laptop, or server) to the Nix-Vibe configuration.'
argument-hint: '<hostname> [desktop|server]'
---
# New Host Scaffolding
## When to Use
- Adding a brand new machine to the Nix-Vibe configuration
- User asks to "add a host", "create a new machine config", or "scaffold a server/laptop"
- Migrating a new device into this flake-based setup
## Procedure
### 1. Gather Information
Before creating files, confirm with the user:
- **Hostname** (e.g., `new-laptop`)
- **Type**: Desktop/laptop (needs GUI) or Server (headless, CLI only)
- **Users** who will have Home Manager configs on this host
- **Any special hardware** (NVIDIA GPU, fingerprint sensor, etc.)
- **Any services** this host should run
### 2. Create Host Directory
```bash
mkdir -p hosts/<hostname>
```
### 3. Create Required Host Files
#### `hosts/<hostname>/hardware-configuration.nix`
Generate on the target machine after NixOS install:
```bash
nixos-generate-config --show-hardware-config > hosts/<hostname>/hardware-configuration.nix
```
If the target machine isn't available yet, create a minimal placeholder:
```nix
# hardware-configuration.nix for <hostname>
# Generated placeholder — run nixos-generate-config on the target machine
{
config,
lib,
pkgs,
...
}:
{
imports = [ ];
boot.initrd.availableKernelModules = [ ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
```
#### `hosts/<hostname>/disko-config.nix`
Copy from an existing host of the same type (desktop vs server) and adjust disk layout:
```bash
cp hosts/x1carbon/disko-config.nix hosts/<hostname>/disko-config.nix
# Then edit to match the target disk layout
```
#### `hosts/<hostname>/configuration.nix`
Use the appropriate template below.
**Desktop/laptop template:**
```nix
{
config,
pkgs,
inputs,
lib,
...
}:
{
imports = [
./hardware-configuration.nix
../../modules/core/common.nix
../../modules/desktop/gui.nix
(import ../../modules/storage/disko.nix {
inherit inputs lib config;
diskoConfigPath = ./disko-config.nix;
})
../../modules/desktop/gnome.nix
../../modules/core/management.nix
../../modules/core/podman.nix
../../modules/core/dev.nix
];
networking.hostName = "<hostname>";
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
}
```
**Server template:**
```nix
{
config,
pkgs,
lib,
inputs,
...
}:
{
imports = [
../../modules/core/common.nix
(import ../../modules/storage/disko.nix {
inherit inputs lib config;
diskoConfigPath = ./disko-config.nix;
})
./hardware-configuration.nix
../../modules/core/podman.nix
];
networking.hostName = "<hostname>";
}
```
### 4. Wire into `flake.nix`
#### Add users in `hostUsers`:
```nix
hostUsers = {
# ...existing hosts...
<hostname> = [ "user1" "user2" ];
};
```
#### Add nixosConfiguration:
If **desktop/laptop** (uses full overlays):
```nix
nixosConfigurations = {
# ...existing configs...
<hostname> = mkNixosSystem "<hostname>" { };
};
```
If **server** (uses serverOverlays):
```nix
nixosConfigurations = {
# ...existing configs...
<hostname> = mkNixosSystem "<hostname>" {
hostOverlays = serverOverlays;
};
};
```
### 5. Create Home Manager User Configs (if needed)
If the host has users without existing Home Manager configs, create:
```bash
mkdir -p home-manager/users
```
Minimal user template (`home-manager/users/<username>.nix`):
```nix
{
config,
pkgs,
lib,
inputs,
...
}:
{
home-manager.users.<username> = {
home.username = "<username>";
home.homeDirectory = "/home/<username>";
home.stateVersion = "24.11";
programs.home-manager.enable = true;
programs.git.enable = true;
};
}
```
### 6. Update README.md
Add the new host to:
- The **Host Roles** section with role description and key features
- The **Software Inventory** table (add a column for the new host)
### 7. Register Host in nix-flake-rebuild Skill
The dry-build loop in [nix-flake-rebuild](../nix-flake-rebuild/SKILL.md) is dynamic (hosts are read from `nixosConfigurations`), so nothing breaks if you skip this — but add `<hostname>` to its **Host Reference** table (with the correct Type and Overlay — `serverOverlays` for servers, Full for desktops/laptops) to keep the overlay reference accurate.
### 8. Validate
Follow the [nix-flake-rebuild](../nix-flake-rebuild/SKILL.md) skill to validate all changes.
## Common Patterns
### Adding Desktop Apps
Import app modules in the host config:
```nix
imports = [
# ...existing imports...
../../modules/desktop/apps/soundux.nix
../../modules/desktop/apps/opencode.nix
];
```
### Adding Services
Import service modules and enable:
```nix
imports = [
# ...existing imports...
../../modules/services/immich.nix
];
services.immich-server.enable = true;
```
### Hardware-Specific Modules
```nix
imports = [
# ...existing imports...
../../modules/hardware/fingerprint.nix # if fingerprint reader
../../modules/hardware/nvidia.nix # if NVIDIA GPU
];
```
For an NVIDIA GPU, enable via the shared option (instead of hand-writing
`hardware.nvidia`):
```nix
my.hardware.nvidia = {
enable = true;
nvidiaSettings = true;
package = config.boot.kernelPackages.nvidiaPackages.legacy_580; # optional
};
```
### Shared Users (petere)
The admin user `petere` is defined once in `modules/core/users.nix` (imported via
`common.nix`). New hosts do **not** re-declare the full `users.users.petere`
block — override only what differs:
```nix
my.users.petere = {
hashedPasswordFile = config.sops.secrets."users/petere-password".path;
subUidStart = 165536; # optional rootless-podman range
subGidStart = 165536;
};
```
`petere` also needs a Home Manager config in `hostUsers` (step 4).