{ config, pkgs, lib, vmixLib, ... }: with lib; { options = { autostart = mkOption { type = types.bool; default = false; description = "Start VM on host boot."; }; enable = mkOption { type = types.bool; default = true; description = "Enable/disable VM service creation."; }; vnc = { enable = mkOption { type = types.bool; default = false; description = "Enable VNC."; }; addr = mkOption { type = types.str; default = "0.0.0.0"; description = "VNC bind address inside the VM namespace."; }; port = mkOption { type = types.ints.between 5900 5999; default = 5900; description = "VNC TCP port inside the VM namespace."; }; forwardHostPort = mkOption { type = types.nullOr types.port; default = null; description = "Optional host TCP port to auto-forward to this VM VNC port."; }; websocketPort = mkOption { type = types.nullOr types.port; default = null; description = "Optional websocket port for VNC (for noVNC-style clients)."; }; passwordFile = mkOption { type = types.nullOr types.str; default = null; description = "Path to a runtime file containing the VNC password. When set, VNC auth is enabled via password-secret."; }; sharePolicy = mkOption { type = types.enum [ "allow-exclusive" "force-shared" "ignore" ]; default = "allow-exclusive"; description = "VNC client sharing policy."; }; }; spice = { enable = mkOption { type = types.bool; default = false; description = "Enable SPICE display server."; }; port = mkOption { type = types.int; default = 5930; description = "SPICE TCP port inside the VM namespace."; }; forwardHostPort = mkOption { type = types.nullOr types.port; default = null; description = "Optional host TCP port to auto-forward to this VM SPICE port."; }; addr = mkOption { type = types.str; default = "0.0.0.0"; description = "SPICE bind address inside the VM namespace."; }; passwordFile = mkOption { type = types.nullOr types.str; default = null; description = "Path to a runtime file containing SPICE password. When set, ticketing is enabled automatically, otherwise ticketing is disabled."; }; agent.enable = mkOption { type = types.bool; default = true; description = "Enable SPICE guest agent channel (clipboard/resolution helpers)."; }; usbRedir = { enable = mkOption { type = types.bool; default = false; description = "Enable SPICE USB redirection channels."; }; channels = mkOption { type = types.ints.between 1 16; default = 4; description = "Number of SPICE USB redirection channels to expose."; }; }; displayDevice = mkOption { type = types.enum [ "virtio" "qxl" "std" "vmware" "none" ]; default = "qxl"; description = "QEMU -vga type to use with SPICE (qxl, virtio, std, vmware, none). macOS has no QXL/virtio-gpu driver: it always uses vmware (or std)."; }; vgamem = mkOption { type = types.nullOr types.int; default = null; description = "Video memory in MB for QXL device. When set, uses -device qxl-vga instead of -vga qxl."; }; }; nographic = mkOption { type = types.bool; default = true; description = "Run QEMU without a graphical window (-nographic)."; }; cpu.cores = mkOption { type = types.int; default = 2; description = "Number of CPU cores."; }; cpu.model = mkOption { type = types.str; default = "host"; description = "CPU model."; }; cpu.hideVirtualized = mkOption { type = types.bool; default = true; description = "Hide hypervisor from guest. Prevents GPU driver Code 43 errors by stripping hypervisor CPUID leaf."; }; kvm = mkOption { type = types.bool; default = true; description = "Enable KVM."; }; arch = mkOption { type = types.str; default = "x86_64"; description = "Architecture of the VM."; }; pc.type = mkOption { type = types.str; default = "q35"; description = "PC type."; }; bios.efi = mkOption { type = types.bool; default = true; description = "Enable EFI BIOS."; }; bios.tpm = mkOption { type = types.bool; default = false; description = "Enable TPM BIOS."; }; mem.size = mkOption { type = types.int; default = 1024; description = "Memory size in MB."; }; mem.balloon = mkOption { type = types.bool; default = false; description = "Enable memory ballooning."; }; disks.os.file = mkOption { type = types.nullOr types.path; default = null; description = "Path to the OS disk image. Null for ISO-only VMs. For Windows, use a vmixLib.windows.* image — config auto-detects via _vmixOsType metadata."; }; disks.os.persist = mkOption { type = types.bool; default = false; description = "Persist OS disk changes. The store image is copied to persistPath on first boot and QEMU writes to that mutable copy."; }; disks.os.persistPath = mkOption { type = types.str; default = ""; description = "Mutable path for the persistent OS disk (e.g. /storage/vms/myvm/os.qcow2). Required when persist = true."; }; disks.iso.file = mkOption { type = types.nullOr (types.either types.path types.str); description = "Path to the ISO file. Can be a Nix store path or a string path to a local file."; default = null; }; disks.add = mkOption { default = {}; type = types.attrsOf (types.submodule { options = { file = mkOption { type = types.str; description = "String literal path to the additional disk."; }; format = mkOption { type = types.str; description = "raw/qcow2 etc"; }; mounts = mkOption { type = types.attrsOf types.str; description = "Mount points for the additional disk."; }; opts = mkOption { type = types.str; description = "additional options in QEMU args for this disk"; }; }; }); description = "Additional disks."; }; shares = mkOption { default = {}; type = types.attrsOf (types.submodule { options = { source = mkOption { type = types.path; description = "Source path for the shared directory."; }; target = mkOption { type = types.str; description = "Target path inside the VM for the shared directory. macOS: the share named `automount` (or the first one) appears at /Volumes/My Shared Files; others are mounted at target through the guest agent."; }; }; }); description = "Shared directories (9p for Linux, virtio-fs via virtiofsd for macOS)."; }; disks.bus = mkOption { type = types.str; default = "virtio"; description = "Bus type for the disks."; }; boot.order = mkOption { type = types.listOf (types.enum [ "os" "iso" "net" "floppy" ]); description = "Boot order."; default = [ "os" "iso" ]; }; boot.menu = mkOption { type = types.bool; default = false; description = "Enable boot menu."; }; nicModel = mkOption { type = types.str; default = "virtio-net-pci"; description = "QEMU NIC device model (e.g. virtio-net-pci, e1000)."; }; windows = { enable = mkOption { type = types.bool; default = false; description = "Enable Windows-optimized QEMU flags. Auto-enabled when disks.os.file carries _vmixOsType = \"windows\" metadata."; }; }; macos = { enable = mkOption { type = types.bool; default = false; description = "Enable macOS QEMU flags (OpenCore/AppleSMC, Skylake CPU spoof, AHCI disk, pinned NIC). Auto-enabled when disks.os.file carries _vmixOsType = \"macos\" metadata."; }; cpu = mkOption { type = types.str; default = vmixLib.macos.qemu.defaultCpu; description = "QEMU -cpu string used for macOS VMs when cpu.model is \"host\"."; }; mac = mkOption { type = types.nullOr types.str; default = null; description = "MAC address of en0. Defaults to the image's macAddress (must match OpenCore's ROM for Apple ID / iMessage)."; }; guestAgent.enable = mkOption { type = types.bool; default = true; description = "Attach Apple's built-in QEMU guest agent (virtio console port org.qemu.guest_agent.0). Socket: /run/vmix/qga-.sock; guest-exec runs as root."; }; homeDisk = { enable = mkOption { type = types.bool; default = false; description = "Persistent home volume: a host disk image attached as virtio-blk, formatted APFS with label `label` by the PE on first start. The image must be generalized with persistHome = true (the user's home is /Volumes/