{ inputs = { flake-parts.url = "github:hercules-ci/flake-parts"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05"; nixpkgs-25_11.url = "github:NixOS/nixpkgs/nixos-25.11"; gtrackmap = { url = "github:gtrackmap/gtrackmap"; inputs.nixpkgs.follows = "nixpkgs"; }; lanzaboote = { url = "github:nix-community/lanzaboote"; inputs.nixpkgs.follows = "nixpkgs"; }; nixos-hardware = { url = "github:NixOS/nixos-hardware/master"; inputs.nixpkgs.follows = "nixpkgs"; }; home-manager = { url = "github:nix-community/home-manager/release-25.11"; inputs.nixpkgs.follows = "nixpkgs"; }; ketchup = { url = "github:repomaa/ketchup"; inputs.nixpkgs.follows = "nixpkgs"; }; workout-sync = { url = "sourcehut:~repomaa/workout-sync"; inputs.nixpkgs.follows = "nixpkgs"; }; hastebin = { url = "sourcehut:~repomaa/hastebin"; inputs.nixpkgs.follows = "nixpkgs"; }; ksoloti-pr.url = "github:repomaa/nixpkgs/pkg/ksoloti"; agenix = { url = "github:ryantm/agenix"; inputs.nixpkgs.follows = "nixpkgs"; }; dnote = { url = "github:dnote/dnote"; flake = false; }; colmena = { url = "github:zhaofengli/colmena"; inputs.nixpkgs.follows = "nixpkgs"; }; syntax-renderer = { url = "sourcehut:~repomaa/syntax-renderer"; flake = false; }; turny = { url = "sourcehut:~repomaa/turny"; inputs.flake-parts.follows = "flake-parts"; inputs.nixpkgs.follows = "nixpkgs"; }; voidauth = { url = "github:repomaa/voidauth/feat/nix-packaging"; inputs.nixpkgs.follows = "nixpkgs-unstable"; inputs.flake-parts.follows = "flake-parts"; }; voxtype = { url = "github:peteonrails/voxtype"; inputs.nixpkgs.follows = "nixpkgs-unstable"; }; tree_hugger = { url = "git+ssh://git@github.com/everii-Group/tree_hugger"; inputs.nixpkgs.follows = "nixpkgs-unstable"; }; models-dev = { url = "github:anomalyco/models.dev"; flake = false; }; noctalia.url = "github:noctalia-dev/noctalia"; niri-flake = { url = "github:sodiboo/niri-flake"; inputs.nixpkgs.follows = "nixpkgs-unstable"; }; nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=latest"; llm-agents = { url = "github:numtide/llm-agents.nix"; inputs.nixpkgs.follows = "nixpkgs-unstable"; }; }; outputs = { flake-parts, agenix, nixpkgs, self, colmena, ... }@inputs: flake-parts.lib.mkFlake { inherit inputs; } ( { withSystem, ... }: let ssh.publicKeys = { yubikey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLIUkESu5NnBi1M0+ZjYrkp6/rIFuwc3aguspf98jmOydNce6l65cnS3GRzc9oWx4lu11ahi87ZuE+pYV+gaHm4="; builder = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFuQaA6JKCOfsfUBI5tzoiYe3tdpLdPfVzeyByx/149C"; }; specialArgs = { inherit inputs ssh self; }; in { systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; perSystem = { pkgs, system, ... }: { devShells.default = pkgs.mkShell { packages = with pkgs; [ agenix.packages.${system}.default colmena.packages.${system}.colmena (writeShellScriptBin "build" '' colmena build --keep-result "$@" '') (writeShellScriptBin "apply" '' colmena apply --keep-result "$@" '') (writeShellScriptBin "apply-local" '' nh os switch . '') (writeShellScriptBin "build-sd" '' set -euo pipefail echo "Building SD image for turny..." nix build .#images.turny --system aarch64-linux --print-build-logs STORE_IMG=$(readlink -f result/sd-image/*.img) if [ -z "$STORE_IMG" ]; then echo "Error: No .img file found in result/sd-image/" exit 1 fi KEY_DIR="$(git rev-parse --show-toplevel)/hosts/turny" if [ ! -f "$KEY_DIR/ssh_host_ed25519_key" ]; then echo "Error: SSH host key not found at $KEY_DIR/ssh_host_ed25519_key" echo "Generate it with: ssh-keygen -t ed25519 -f hosts/turny/ssh_host_ed25519_key -N \"\" -C turny" exit 1 fi IMG="/tmp/turny-sd-image.img" echo "Copying image to writable location: $IMG" cp "$STORE_IMG" "$IMG" echo "Injecting SSH host key into image..." LOOP=$(sudo losetup --show -P -f "$IMG") MNT=$(sudo mktemp -d) cleanup() { sudo umount "$MNT" 2>/dev/null || true sudo rmdir "$MNT" 2>/dev/null || true sudo losetup -d "$LOOP" 2>/dev/null || true } trap cleanup EXIT sudo mount "''${LOOP}p2" "$MNT" sudo mkdir -p "$MNT/etc/ssh" sudo cp "$KEY_DIR/ssh_host_ed25519_key" "$MNT/etc/ssh/ssh_host_ed25519_key" sudo cp "$KEY_DIR/ssh_host_ed25519_key.pub" "$MNT/etc/ssh/ssh_host_ed25519_key.pub" sudo chmod 600 "$MNT/etc/ssh/ssh_host_ed25519_key" sudo chmod 644 "$MNT/etc/ssh/ssh_host_ed25519_key.pub" echo "Done! Image ready at: $IMG" echo "Flash with: sudo dd if=$IMG of=/dev/sdX bs=4M conv=fsync status=progress" '') ]; }; }; flake = { nixosConfigurations = let mkConfiguration = name: nixpkgs.lib.nixosSystem { inherit specialArgs; modules = [ ./modules ./hosts/${name} ]; }; in { radish = mkConfiguration "radish"; freun-dev = mkConfiguration "freun-dev"; apu = mkConfiguration "apu"; turny = mkConfiguration "turny"; }; images.turny = self.nixosConfigurations.turny.config.system.build.sdImage; dockerImages = nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] ( system: withSystem system ( { pkgs, ... }: { node = let setupDirs = pkgs.runCommand "setup-dirs" { } '' mkdir -p $out/tmp $out/root $out/var/tmp chmod 1777 $out/tmp $out/var/tmp ''; in pkgs.dockerTools.buildLayeredImage { name = "node"; tag = "latest"; contents = with pkgs; [ nodejs nix busybox bash skopeo cacert git setupDirs (writeTextFile { name = "etc-nix-nix-conf"; destination = "/etc/nix/nix.conf"; text = '' build-users-group = experimental-features = nix-command flakes ''; }) ]; config = { Env = [ "SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt" "NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-bundle.crt" "HOME=/root" ]; }; }; } ) ); colmenaHive = colmena.lib.makeHive self.outputs.colmena; colmena = let deploymentOptions = { freun-dev = { targetHost = "freun.dev"; buildOnTarget = true; }; radish = { allowLocalDeployment = true; targetHost = null; }; turny = { targetHost = "10.10.1.233"; }; }; in { meta = { inherit specialArgs; nixpkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ ]; }; }; } // builtins.mapAttrs (name: config: { imports = config._module.args.modules; deployment = if builtins.hasAttr name deploymentOptions then deploymentOptions.${name} else { }; }) self.nixosConfigurations; }; } ); nixConfig = { extra-substituters = [ "https://noctalia.cachix.org" ]; extra-trusted-public-keys = [ "noctalia.cachix.org-1:pCOR47nnMEo5thcxNDtzWpOxNFQsBRglJzxWPp3dkU4=" ]; }; }