feat: flake inputs/outputs and settings.nix entry point

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-06-28 06:48:06 +02:00
commit d37ac719d3
3 changed files with 3083 additions and 0 deletions

2469
flake.lock generated Normal file

File diff suppressed because it is too large Load diff

575
flake.nix Normal file
View file

@ -0,0 +1,575 @@
{
description = "Omnixient - NixOS configuration for modern development";
inputs = {
# Nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
# True bleeding-edge nixpkgs-unstable channel. omni's primary
# `nixpkgs` is nixos-unstable (tested unstable); this is the
# untested channel used by lib/overlays.nix to pin a handful of
# fast-moving packages (claude-code, gh, direnv). Unused until
# mkSystem is wired in (phase D).
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
# Unified server-deploy flake. Source of truth for which refs
# ship to which host; dev-env walks this flake's inputs to
# auto-populate the project list (see modules/dev-env/config.nix)
# and resolves --override-input targets for `dev-deploy --local`.
# Named after the forgejo repo so DEVENV_DEPLOY_FLAKE_INPUT and
# the on-disk clone directory match.
server-deploy.url = "git+ssh://forgejo@git.atitlan.io/aiolabs/server-deploy";
# Home manager
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
# nixos-hardware — per-model NixOS modules (kernel pins, GPU/CPU
# defaults, firmware tooling) for common hardware. bohm is a
# Framework Desktop (AMD Ryzen AI Max 300 series), so we import
# `nixosModules.framework-desktop-amd-ai-max-300-series` in
# hosts/omni/default.nix. gizmo is a Framework Laptop 12, but
# runs Arch — if it ever migrates to NixOS, the matching module
# is `nixosModules.framework-12-13th-gen-intel`.
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
# Hyprland
# Pinned to v0.54.3 — v0.55.0 (rev 70fd412) crashes on `togglegroup`
# teardown: CGroup::destroy() throws an uncaught std::out_of_range.
# Remove the tag to track latest once the upstream group regression is fixed.
hyprland = {
url = "github:hyprwm/Hyprland/v0.54.3";
inputs.nixpkgs.follows = "nixpkgs";
};
# Hyprland plugins
hyprland-plugins = {
url = "github:hyprwm/hyprland-plugins";
inputs.hyprland.follows = "hyprland";
};
# Nix colors for automatic color scheme generation
nix-colors = {
url = "github:misterio77/nix-colors";
};
# Stylix for theming
stylix = {
url = "github:danth/stylix";
inputs.nixpkgs.follows = "nixpkgs";
};
# NUR for additional packages
nur.url = "github:nix-community/NUR";
# Walker app launcher + Elephant backend
elephant = {
url = "github:abenz1267/elephant";
inputs.nixpkgs.follows = "nixpkgs";
};
walker = {
url = "github:abenz1267/walker";
inputs.nixpkgs.follows = "nixpkgs";
inputs.elephant.follows = "elephant";
};
# sops-nix — declarative secrets via age-encrypted YAML files.
# Decryption happens at activation time on the target host; secret
# values are exposed to services as files under /run/secrets/.
# The omni host's age key lives at
# ~/.config/sops/age/keys.txt (same `admin` recipient as
# ~/dev/deploy/server-deploy/.sops.yaml). See .sops.yaml +
# modules/secrets.nix for wiring.
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# LazyVim packaged as a home-manager module. Tracks LazyVim
# releases upstream and pins every plugin via the nix store
# ("dev mode" symlinks) so there is no runtime download. We
# pin to a specific tag rather than tracking `main` so a
# broken upstream release can never silently break a fresh
# install. Bump intentionally on each LazyVim release.
lazyvim = {
url = "github:pfassina/lazyvim-nix/v15.15.0";
inputs.nixpkgs.follows = "nixpkgs";
};
# nix-bitcoin — hardened Bitcoin/Lightning node modules, consumed by
# the default-disabled bitcoin pack. Follows our nixpkgs for a single
# package set; nix-bitcoin pins its own nixpkgs upstream for tested
# builds, so if a service fails to build once the pack is enabled,
# consider dropping this `follows`.
nix-bitcoin = {
url = "github:fort-nix/nix-bitcoin/release";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
self,
nixpkgs,
home-manager,
...
}@inputs:
let
system = "x86_64-linux";
settings = import ./settings.nix;
# Overlays applied uniformly to every host built via mkSystem.
# Combines the lib/overlays.nix nixpkgs-unstable pins with the
# nur overlay omni already used. The neovim-nightly-overlay
# was dropped because it cascade-rebuilds every neovim plugin
# from source (cache miss on cache.nixos.org), which surfaced
# broken upstream tests (fzf-lua screenshot test) and balloons
# build time. LazyVim is provided declaratively via the
# `lazyvim` flake input (a home-manager module) — see
# home.nix `programs.lazyvim` — so we don't need a system
# neovim with the full plugin set baked in.
overlays = (import ./lib/overlays.nix { inherit inputs; }) ++ [
inputs.nur.overlays.default
];
# Uniform host constructor. See lib/mksystem.nix for the shape.
mkSystem = import ./lib/mksystem.nix { inherit nixpkgs overlays inputs; };
# pkgs used for devShells, packages, and apps outputs below.
# The nixosConfigurations get their own pkgs via mksystem's
# `{ nixpkgs.overlays = overlays; }` module injection.
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
inherit overlays;
};
# Interactive regtest dev VM (`nix run .#regtest`). Shares the node
# config with the CI test (tests/regtest-node.nix); the interactive
# layer (SSH, operator login, helpers) is tests/regtest-interactive.nix.
regtestVm = nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs settings; };
modules = [
{ nixpkgs.hostPlatform = system; }
{ nixpkgs.config.allowUnfree = true; }
# qemu-vm.nix provides `system.build.vm` plus the virtualisation.*
# options (cores/memorySize/graphics/forwardPorts) that the node
# and interactive modules set. The nixosTest framework imports it
# automatically; a plain nixosSystem must do so explicitly.
(
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ];
}
)
inputs.nix-bitcoin.nixosModules.default
./tests/regtest-node.nix
./tests/regtest-interactive.nix
];
};
# `nix run .#regtest` — boot the VM headless, drop into an operator
# SSH shell, tear the VM down on exit. Ephemeral disk in a tmp file.
regtestRunner = pkgs.writeShellApplication {
name = "regtest";
runtimeInputs = with pkgs; [
sshpass
openssh
coreutils
];
text = ''
vm_script=${regtestVm.config.system.build.vm}/bin/run-regtest-vm
img=$(mktemp -u --suffix=.qcow2)
log=$(mktemp)
export NIX_DISK_IMAGE="$img"
ssh_opts=(-p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR)
cleanup() {
if [ -n "''${vm_pid:-}" ]; then kill "$vm_pid" 2>/dev/null || true; fi
rm -f "$img" "$log"
}
trap cleanup EXIT INT TERM
echo "🥾 booting regtest VM (headless) first boot generates node secrets + mines 110 blocks"
"$vm_script" >"$log" 2>&1 &
vm_pid=$!
echo " waiting for SSH on localhost:2222"
ready=
for _ in $(seq 1 120); do
if ! kill -0 "$vm_pid" 2>/dev/null; then
echo " VM exited early; last log lines:"; tail -n 20 "$log"; exit 1
fi
if sshpass -p password ssh "''${ssh_opts[@]}" -o ConnectTimeout=2 operator@localhost true 2>/dev/null; then
ready=1; break
fi
sleep 2
done
if [ "$ready" != 1 ]; then
echo " SSH never came up; last log lines:"; tail -n 20 "$log"; exit 1
fi
echo " connected run 'regtest-fund' to set up a channel; 'exit' to shut down."
sshpass -p password ssh "''${ssh_opts[@]}" operator@localhost || true
'';
};
in
{
# NixOS configurations.
nixosConfigurations = {
# Main dev box. Uses the mksystem convention (hosts/omni/ +
# users/user/home-manager.nix shims — see commit dc9d70b).
#
# modules = [ ... ] is the escape hatch for host-specific
# home-manager options that mksystem doesn't expose directly,
# like sharedModules for nix-colors integration.
omni = mkSystem "omni" {
inherit system;
user = settings.user;
devEnv = true;
extraSpecialArgs = { inherit settings; };
extraHmArgs = { inherit settings; };
modules = [
{
home-manager.sharedModules = [
inputs.nix-colors.homeManagerModules.default
inputs.lazyvim.homeManagerModules.default
inputs.walker.homeManagerModules.default
];
}
];
};
# Copy-me template host (hosts/example/). Kept as a real,
# build-checked target so the template can't silently rot — its
# placeholder hardware-configuration.nix uses by-label devices
# that won't match real hardware, so don't `switch` to it. Adopters
# copy hosts/example → hosts/<name> and rename this block. See
# hosts/example/default.nix and docs/getting-started.md.
example = mkSystem "example" {
inherit system;
user = settings.user;
extraSpecialArgs = { inherit settings; };
extraHmArgs = { inherit settings; };
modules = [
{
home-manager.sharedModules = [
inputs.nix-colors.homeManagerModules.default
inputs.lazyvim.homeManagerModules.default
inputs.walker.homeManagerModules.default
];
}
];
};
# ISO image for live USB/DVD. This is a variant rather than a
# normal host, so it stays as a direct nixosSystem call — we
# don't force every variant through mksystem. It reuses
# omni's home.nix but under a "nixos" user that only exists
# in the ISO context.
omni-iso = nixpkgs.lib.nixosSystem {
specialArgs = {
inherit inputs;
settings = settings // {
user = "nixos";
};
currentSystemName = "omni-iso";
currentSystemUser = "nixos";
};
modules = [
{ nixpkgs.hostPlatform = system; }
{ nixpkgs.overlays = overlays; }
{ nixpkgs.config.allowUnfree = true; }
./iso.nix
home-manager.nixosModules.home-manager
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
extraSpecialArgs = {
inherit inputs;
settings = settings // {
user = "nixos";
};
currentSystemName = "omni-iso";
currentSystemUser = "nixos";
};
users.nixos = import ./home.nix;
sharedModules = [
inputs.nix-colors.homeManagerModules.default
inputs.lazyvim.homeManagerModules.default
inputs.walker.homeManagerModules.default
];
};
}
];
};
};
# Reusable packs as importable NixOS modules (Misterio77-style,
# framework-free). A second host (gizmo) and third parties consume
# the same definitions with different subsets. The lnbits / aiolabs
# / bitcoin packs are standalone-importable — usable on a non-omni
# NixOS without enabling omni core.
nixosModules = {
lnbits = import ./modules/packs/lnbits.nix;
aiolabs = import ./modules/packs/aiolabs.nix;
bitcoin = import ./modules/packs/bitcoin.nix;
media = import ./modules/packs/media.nix;
development = import ./modules/packs/development.nix;
gaming = import ./modules/packs/gaming.nix;
office = import ./modules/packs/office.nix;
containers = import ./modules/packs/containers.nix;
};
# Flake checks — run by `nix flake check`. Lightweight targets
# that exercise the dev-env module schema end-to-end without
# loading the full omni system. Each check renders a small
# file (JSON or bash), so they build in a second or two even
# without a binary cache. See modules/dev-env/tests/smoke.nix
# for what is exercised.
checks.${system} =
let
devEnvSmoke = import ./modules/dev-env/tests/smoke.nix {
inherit nixpkgs;
home-manager = inputs.home-manager;
};
in
{
dev-env-projects-json = devEnvSmoke.config.environment.etc."dev-env/projects.json".source;
dev-env-config-sh = devEnvSmoke.config.environment.etc."dev-env/config.sh".source;
dev-env-tmux-sessions = devEnvSmoke.config.environment.etc."dev-env/tmux-sessions.json".source;
# Headless VM boot test — pass/fail signal for autonomous refactor
# runs in ~/nixos-refactor/. See tests/refactor-smoke.nix.
refactor-smoke = import ./tests/refactor-smoke.nix {
inherit nixpkgs system;
};
# NixOS-native Lightning regtest suite (aiolabs/omnixient#27):
# bitcoind(regtest) + Core Lightning + LND in one VM, driving a
# real fund → open-channel → pay → settle flow. See
# tests/regtest-core.nix.
regtest-core = import ./tests/regtest-core.nix {
inherit nixpkgs system;
nix-bitcoin = inputs.nix-bitcoin;
};
};
# Development shells
devShells.${system} = {
default = pkgs.mkShell {
packages = with pkgs; [
# Development tools
git
# neovim (configured via home-manager)
ripgrep
fd
bat
eza
fzf
zoxide
starship
lazygit
gh
# Language servers and formatters
nil # Nix LSP
nixfmt
statix
deadnix
# Build tools
gnumake
gcc
nodejs
python3
rustc
cargo
go
];
shellHook = ''
echo "🚀 Welcome to Omnixient development environment!"
echo ""
echo "Available commands:"
echo " omni-rebuild - Rebuild system configuration"
echo " omni-update - Update flake inputs"
echo " omni-clean - Garbage collect nix store"
echo ""
# Setup aliases
alias omni-rebuild="sudo nixos-rebuild switch --flake .#omni"
alias omni-update="nix flake update"
alias omni-clean="nix-collect-garbage -d"
# Initialize starship prompt
eval "$(starship init bash)"
'';
};
# Python development
python = pkgs.mkShell {
packages = with pkgs; [
python3
python3Packages.pip
python3Packages.virtualenv
python3Packages.ipython
python3Packages.black
python3Packages.pylint
python3Packages.pytest
ruff
];
};
# Node.js development
node = pkgs.mkShell {
packages = with pkgs; [
nodejs
pnpm
yarn
typescript
eslint
prettier
];
};
# Rust development
rust = pkgs.mkShell {
packages = with pkgs; [
rustc
cargo
rustfmt
rust-analyzer
clippy
];
};
};
# Packages that can be built
packages.${system} = {
# Omnixient scripts as packages
omni-scripts = pkgs.callPackage ./packages/scripts.nix { };
# Plymouth theme package
plymouth-theme-omni = pkgs.callPackage ./packages/plymouth-theme.nix { };
# ISO image
iso = self.nixosConfigurations.omni-iso.config.system.build.isoImage;
# Interactive regtest dev VM run-script (booted by `nix run .#regtest`).
regtest-vm = regtestVm.config.system.build.vm;
# Default package points to ISO
default = self.packages.${system}.iso;
};
# Apps that can be run
apps.${system} = {
# Interactive Lightning regtest dev VM — boots the stack headless
# and drops you into an operator SSH shell. See docs/regtest.md.
regtest = {
type = "app";
program = "${regtestRunner}/bin/regtest";
};
# Installer
installer = {
type = "app";
program = "${pkgs.writeShellScriptBin "omni-install" ''
#!/usr/bin/env bash
set -e
echo "🚀 Omnixient NixOS Installer"
echo "========================"
echo ""
# Check if running on NixOS
if [ ! -f /etc/nixos/configuration.nix ]; then
echo "Error: This installer must be run on a NixOS system"
exit 1
fi
echo "This will install Omnixient configuration to your NixOS system."
read -p "Continue? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
# Backup existing configuration
echo "📦 Backing up existing configuration..."
sudo cp -r /etc/nixos /etc/nixos.backup.$(date +%Y%m%d-%H%M%S)
# Copy new configuration
echo "📝 Installing Omnixient configuration..."
sudo cp -r ${self}/* /etc/nixos/
# Initialize flake
echo "🔧 Initializing flake..."
cd /etc/nixos
sudo git init
sudo git add -A
# Rebuild
echo "🏗 Rebuilding system..."
sudo nixos-rebuild switch --flake /etc/nixos#omni
echo ""
echo " Installation complete!"
echo "🎉 Welcome to Omnixient!"
''}/bin/omni-install";
};
# ISO builder
build-iso = {
type = "app";
program = "${pkgs.writeShellScriptBin "omni-build-iso" ''
#!/usr/bin/env bash
set -e
echo "🏗 Building Omnixient ISO Image"
echo "============================"
echo ""
echo "📦 Building ISO image..."
echo " This may take a while depending on your system..."
echo ""
# Build the ISO
nix build .#iso
# Check if build was successful
if [ -L "./result" ]; then
iso_path=$(readlink -f ./result)
iso_file=$(find "$iso_path" -name "*.iso" | head -1)
if [ -n "$iso_file" ]; then
iso_size=$(du -h "$iso_file" | cut -f1)
echo ""
echo " ISO build complete!"
echo "📁 Location: $iso_file"
echo "📏 Size: $iso_size"
echo ""
echo "🚀 You can now:"
echo " Flash to USB: dd if='$iso_file' of=/dev/sdX bs=4M status=progress"
echo " Burn to DVD: Use your favorite burning software"
echo " Test in VM: qemu-system-x86_64 -cdrom '$iso_file' -m 4G -enable-kvm"
echo ""
else
echo " ISO file not found in build result"
exit 1
fi
else
echo " Build failed - result symlink not found"
exit 1
fi
''}/bin/omni-build-iso";
};
};
};
}

39
settings.nix Normal file
View file

@ -0,0 +1,39 @@
# Omnixient User Settings
#
# This is the ONE file every adopter edits to make Omnixient their own.
# Everything machine- or person-specific is funnelled through here and
# threaded into the modules — you shouldn't need to hunt through the tree.
#
# (Your hardware scan is the only other per-machine piece: see
# hosts/<name>/hardware-configuration.nix and docs/getting-started.md.)
{
# --- Identity ---
user = "padreug"; # your Linux username (the home dir, primary account)
gitName = "Padreug"; # git author name
gitEmail = "padreug@aiolabs.dev"; # git author email
hostName = "omni"; # machine hostname == hosts/<hostName>/ directory
# Find yours with `timedatectl list-timezones`, or the "TZ identifier"
# column at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
timeZone = "Europe/Paris"; # e.g. "America/New_York", "Asia/Tokyo"
# --- Desktop theme ---
# One of modules/themes/*.nix (without the .nix). Switch at runtime with
# `omni-theme <name>`; this is just the default a fresh build boots with.
theme = "gruvbox";
# --- SSH public keys ---
# Authorized to log into this machine's `user` account over SSH. Paste
# the contents of your ~/.ssh/id_ed25519.pub (or .pub of choice). Empty
# list = no key-based SSH logins.
sshKeys = [
# "ssh-ed25519 AAAAC3Nza... you@host"
];
# --- NixOS state version ---
# CRITICAL: set this to the NixOS release you FIRST installed with, and
# then NEVER change it. It pins stateful defaults (databases, etc.) for
# backwards compatibility; bumping it on an existing system can silently
# break data. It is NOT your current NixOS version. On a fresh install,
# use the release you installed from (e.g. "24.05", "24.11", "25.05").
stateVersion = "24.05";
}