feat(modules): users, scripts, menus, fastfetch, walker, cache, colors, bootstrap

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

45
modules/cache.nix Normal file
View file

@ -0,0 +1,45 @@
# Binary cache configuration.
#
# Substituters and trusted public keys for cache.nixos.org and
# nix-community, plus a stub for the aiolabs cache (uncomment when
# configured). Imported by every host that wants pre-built artifacts
# instead of compiling from source.
#
# Why this exists as its own module: the optimize-deploys/unified flake
# notes that host1/host3/host2 share ~90% of derivations, so the second
# and third deploys would be near-instant once a cache is set up. Same
# applies for the dev box rebuilds. Rather than scatter substituter
# configuration across every host, define it once.
#
# Pushing to the cache is one Makefile target (`make cache`) — see the
# top-level Makefile.
{ ... }:
{
nix.settings = {
substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
# Uncomment when the aiolabs cache is configured.
# "https://aiolabs-nix.cachix.org"
];
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
# Add the aiolabs cache public key here once we generate it:
# cachix authtoken <token>
# cachix create aiolabs-nix
# The public key is shown after `cachix create`.
# "aiolabs-nix.cachix.org-1:..."
];
# Allow more substituters at runtime via `--option extra-substituters`
# without editing this file. Useful for one-off testing.
trusted-substituters = [
"https://cache.nixos.org"
"https://nix-community.cachix.org"
];
};
}

165
modules/colors.nix Normal file
View file

@ -0,0 +1,165 @@
{
config,
pkgs,
lib,
inputs,
...
}:
let
inherit (lib)
mkIf
mkMerge
optionals
optionalString
;
cfg = config.omni;
# Function to generate colors from wallpaper using imagemagick
generateColorsFromWallpaper =
wallpaperPath:
pkgs.writeShellScriptBin "generate-colors" ''
#!/usr/bin/env bash
# Extract dominant colors from wallpaper using imagemagick
colors=$(${pkgs.imagemagick}/bin/convert "${wallpaperPath}" -resize 1x1 -format "%[pixel:u]" info:)
# Generate a simple color scheme based on the dominant color
# This is a simplified approach - ideally would use a more sophisticated algorithm
echo "# Generated color scheme from wallpaper: ${wallpaperPath}"
echo "# Dominant color: $colors"
# For now, we'll use predefined schemes that match common wallpaper types
# In a real implementation, this would analyze the image and generate appropriate colors
'';
# Default color schemes for common wallpaper types
fallbackColorSchemes = {
dark = inputs.nix-colors.colorSchemes.tokyo-night-dark or null;
light = inputs.nix-colors.colorSchemes.tokyo-night-light or null;
blue = inputs.nix-colors.colorSchemes.nord or null;
purple = inputs.nix-colors.colorSchemes.catppuccin-mocha or null;
green = inputs.nix-colors.colorSchemes.gruvbox-dark-medium or null;
};
# Select color scheme based on wallpaper or user preference
selectedColorScheme =
if cfg.colorScheme != null then
cfg.colorScheme
else if cfg.wallpaper != null && cfg.features.autoColors then
# TODO: Implement actual color analysis
# For now, use a sensible default based on theme
fallbackColorSchemes.${cfg.theme} or fallbackColorSchemes.dark
else
# Use theme-based color scheme
fallbackColorSchemes.${cfg.theme} or fallbackColorSchemes.dark;
in
{
config = mkIf (cfg.enable or true) (mkMerge [
# User-specific configuration using shared helpers
({
home-manager.users.${cfg.user} = mkIf (selectedColorScheme != null) {
colorScheme = selectedColorScheme;
# Add packages for color management
home.packages =
with pkgs;
[
imagemagick # For color extraction from images
]
++ optionals (cfg.features.customThemes or false || cfg.features.wallpaperEffects or false) [
# Additional packages for advanced color analysis
python3Packages.pillow # For more sophisticated image analysis
python3Packages.colorthief # For extracting color palettes
]
++ optionals (cfg.wallpaper != null) [
# Generate wallpaper setter script that respects colors
(pkgs.writeShellScriptBin "set-omni-wallpaper" ''
WALLPAPER_PATH="${cfg.wallpaper}"
echo "Setting wallpaper: $WALLPAPER_PATH"
# Set wallpaper with awww
if command -v awww &> /dev/null; then
awww img "$WALLPAPER_PATH" --transition-type wipe --transition-angle 30 --transition-step 90
else
echo "awww not found, please install awww for wallpaper support"
fi
# Optionally generate new colors from wallpaper
${optionalString (cfg.features.wallpaperEffects or false) ''
echo "Generating colors from wallpaper..."
# This would trigger a system rebuild with new colors
# For now, just notify the user
echo "Note: Automatic color generation requires system rebuild"
echo "Consider adding this wallpaper to your configuration and rebuilding"
''}
'')
];
};
})
# System-level configuration
{
# System-level packages for color management
environment.systemPackages = with pkgs; [
# Color utilities
imagemagick
# Wallpaper utilities
awww # Wayland wallpaper daemon
# Script to help users set up automatic colors
(writeShellScriptBin "omni-setup-colors" ''
#!/usr/bin/env bash
echo "Omnixient Color Setup"
echo "=================="
echo ""
echo "Current configuration:"
echo " Theme: ${cfg.theme}"
echo " Preset: ${if cfg.preset != null then cfg.preset else "none"}"
echo " Custom Themes: ${if cfg.features.customThemes or false then "enabled" else "disabled"}"
echo " Wallpaper Effects: ${
if cfg.features.wallpaperEffects or false then "enabled" else "disabled"
}"
echo " Wallpaper: ${if cfg.wallpaper != null then toString cfg.wallpaper else "not set"}"
echo " Color Scheme: ${if cfg.colorScheme != null then "custom" else "theme-based"}"
echo ""
${optionalString (!(cfg.features.wallpaperEffects or false)) ''
echo "To enable automatic color generation:"
echo " 1. Set omni.features.wallpaperEffects = true; in your configuration"
echo " 2. Set omni.wallpaper = /path/to/your/wallpaper.jpg;"
echo " 3. Rebuild your system with: omni-rebuild"
echo ""
''}
${optionalString ((cfg.features.wallpaperEffects or false) && cfg.wallpaper == null) ''
echo "Wallpaper effects are enabled but no wallpaper is set."
echo "Set omni.wallpaper = /path/to/your/wallpaper.jpg; in your configuration."
echo ""
''}
echo "Available nix-colors schemes:"
echo " - tokyo-night-dark, tokyo-night-light"
echo " - catppuccin-mocha, catppuccin-latte"
echo " - gruvbox-dark-medium, gruvbox-light-medium"
echo " - nord"
echo " - everforest-dark-medium"
echo " - rose-pine, rose-pine-dawn"
echo ""
echo "To use a specific scheme:"
echo ' omni.colorScheme = inputs.nix-colors.colorSchemes.SCHEME_NAME;'
'')
];
# Export color information for other modules to use
environment.variables = mkIf (selectedColorScheme != null) {
OMNI_COLOR_SCHEME = selectedColorScheme.slug or "unknown";
};
}
]);
}

221
modules/fastfetch.nix Normal file
View file

@ -0,0 +1,221 @@
{
config,
pkgs,
lib,
...
}:
# Fastfetch system information display for Omnixient
# Beautiful system information with Omnixient branding
let
inherit (lib) mkIf;
cfg = config.omni;
omni = config.omni.lib;
in
{
config = mkIf (cfg.enable or true) {
# Add fastfetch and convenience scripts to system packages
environment.systemPackages =
(with pkgs; [
fastfetch
])
++ [
# Convenience scripts
(omni.makeScript "omni-info" "Show Omnixient system information" ''
fastfetch --config /etc/omni/fastfetch/config.jsonc
'')
(omni.makeScript "omni-about" "Show Omnixient about screen" ''
clear
cat /etc/omni/branding/about.txt
echo
echo "Theme: ${cfg.theme}"
echo "Preset: ${cfg.preset or "custom"}"
echo "User: ${cfg.user}"
echo "NixOS Version: $(nixos-version)"
echo
echo "Visit: https://github.com/TheArctesian/omnixy"
'')
];
# Create Omnixient branding directory
environment.etc."omni/branding/logo.txt".text = ''
Declarative NixOS Configuration
'';
environment.etc."omni/branding/about.txt".text = ''
🚀 Declarative 🎨 Beautiful Fast
'';
# Create fastfetch configuration
environment.etc."omni/fastfetch/config.jsonc".text = ''
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "file",
"source": "/etc/omni/branding/about.txt",
"color": {
"1": "cyan",
"2": "blue"
},
"padding": {
"top": 1,
"right": 4,
"left": 2
}
},
"modules": [
"break",
{
"type": "custom",
"format": "\u001b[90m Hardware "
},
{
"type": "host",
"key": " 󰌢 Host",
"keyColor": "cyan"
},
{
"type": "cpu",
"key": " 󰻠 CPU",
"keyColor": "cyan"
},
{
"type": "gpu",
"key": " 󰍛 GPU",
"keyColor": "cyan"
},
{
"type": "memory",
"key": " 󰍛 Memory",
"keyColor": "cyan"
},
{
"type": "disk",
"key": " 󰋊 Disk (/)",
"keyColor": "cyan"
},
{
"type": "custom",
"format": "\u001b[90m Software "
},
{
"type": "os",
"key": " 󰣇 OS",
"keyColor": "blue"
},
{
"type": "kernel",
"key": " 󰌽 Kernel",
"keyColor": "blue"
},
{
"type": "de",
"key": " 󰧨 DE",
"keyColor": "blue"
},
{
"type": "wm",
"key": " 󰖸 WM",
"keyColor": "blue"
},
{
"type": "wmtheme",
"key": " 󰏘 Theme",
"keyColor": "blue"
},
{
"type": "shell",
"key": " 󰆍 Shell",
"keyColor": "blue"
},
{
"type": "terminal",
"key": " 󰆍 Terminal",
"keyColor": "blue"
},
{
"type": "custom",
"format": "\u001b[90m Omnixient "
},
{
"type": "custom",
"format": " 󰣇 Theme: ${cfg.theme}",
"keyColor": "magenta"
},
{
"type": "custom",
"format": " 󰣇 Preset: ${cfg.preset or "custom"}",
"keyColor": "magenta"
},
{
"type": "custom",
"format": " 󰣇 User: ${cfg.user}",
"keyColor": "magenta"
},
{
"type": "packages",
"key": " 󰏖 Packages",
"keyColor": "magenta"
},
{
"type": "custom",
"format": "\u001b[90m"
},
"break"
]
}
'';
# Convenience scripts are now consolidated above
# Add to user environment
home-manager.users.${config.omni.user} = {
# Set XDG config dir for fastfetch
xdg.configFile."fastfetch/config.jsonc".source =
config.environment.etc."omni/fastfetch/config.jsonc".source;
# Add shell aliases
programs.bash.shellAliases = {
neofetch = "omni-info";
screenfetch = "omni-info";
sysinfo = "omni-info";
about = "omni-about";
};
programs.zsh.shellAliases = {
neofetch = "omni-info";
screenfetch = "omni-info";
sysinfo = "omni-info";
about = "omni-about";
};
programs.fish.shellAliases = {
neofetch = "omni-info";
screenfetch = "omni-info";
sysinfo = "omni-info";
about = "omni-about";
};
};
};
}

View file

@ -0,0 +1,69 @@
# modules/home-manager-bootstrap.nix
#
# Pre-create the directory tree that the home-manager activation
# script expects to exist on a fresh first boot. Without these
# rules, `home-manager-user.service` crashes in (at least) three
# different places — each one only visible after fixing the
# previous — making first-boot of any clean install fail with a
# misleading error.
#
# This module is imported by both:
# - lib/mksystem.nix (for normal hosts), and
# - iso.nix (for the live ISO),
# so the bootstrap is consistent across both code paths. It is
# intentionally a separate module rather than inlined in mksystem
# so the ISO — which bypasses mksystem — does not silently miss
# the fix.
#
# Reads `config.omni.user`, which is the canonical "main user"
# option set by modules/core.nix. Does nothing if that option is
# unset (e.g. during a flake check that does not set up users).
#
# The bugs this fixes:
#
# 1. The "find a profile dir" check in
# home-manager-generation/activate (around line 90 of the
# generated script) needs $HOME/.local/state/nix/profiles
# OR /nix/var/nix/profiles/per-user/$USER to exist. The
# nix-daemon only creates the per-user dir lazily on the
# user's first nix command, so on a fresh boot neither path
# exists. Symptom: "Could not find suitable profile
# directory" → service fails.
#
# 2. After (1) is fixed, `nix-store --realise ... --add-root
# $HOME/.local/state/home-manager/gcroots/new-home` fails
# because the activate script declares `hmGcrootsDir` but
# never `mkdir -p`s it. nix-store will not create parent
# dirs for --add-root. Symptom: silent exit, status 1, no
# error in journal.
#
# 3. After (2) is fixed, `linkGeneration` fails with
# "Permission denied" creating `~/.local/share/dev-env/...`.
# modules/lib.nix declares `d /home/$USER/.local/share/
# omni ...` and systemd-tmpfiles auto-creates the missing
# intermediate `.local/share` parent as root:root, which
# then blocks the user-running activation. Pinning the
# `.local/share` parent here keeps it user-owned regardless
# of declaration order.
#
# tmpfiles `d` rules do not recursively create parents, so each
# level of the tree is spelled out explicitly.
{ config, lib, ... }:
let
user = config.omni.user or null;
in
{
config = lib.mkIf (user != null) {
systemd.tmpfiles.rules = [
"d /nix/var/nix/profiles/per-user/${user} 0755 ${user} users -"
"d /nix/var/nix/gcroots/per-user/${user} 0755 ${user} users -"
"d /home/${user}/.local 0755 ${user} users -"
"d /home/${user}/.local/share 0755 ${user} users -"
"d /home/${user}/.local/state 0755 ${user} users -"
"d /home/${user}/.local/state/home-manager 0755 ${user} users -"
"d /home/${user}/.local/state/home-manager/gcroots 0755 ${user} users -"
];
};
}

534
modules/menus.nix Normal file
View file

@ -0,0 +1,534 @@
{
config,
pkgs,
lib,
...
}:
# Interactive menu system for Omnixient
# Terminal-based menus for system management and productivity
let
inherit (lib) mkIf mkDefault;
cfg = config.omni;
omni = config.omni.lib;
in
{
config = mkIf (cfg.enable or true) {
# Interactive menu scripts
environment.systemPackages = [
# Main Omnixient menu
(omni.makeScript "omni-menu" "Interactive Omnixient system menu" ''
#!/bin/bash
# Colors for terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
NC='\033[0m' # No Color
show_header() {
clear
echo -e "''${CYAN}"
echo " "
echo " "
echo " "
echo " "
echo " "
echo " "
echo -e "''${NC}"
echo -e "''${WHITE} 🚀 Declarative 🎨 Beautiful Fast''${NC}"
echo
echo -e "''${BLUE}''${NC}"
echo -e "''${WHITE} Theme: ''${YELLOW}${cfg.theme}''${WHITE} User: ''${GREEN}${cfg.user}''${WHITE} Preset: ''${PURPLE}${cfg.preset or "custom"}''${NC}"
echo -e "''${BLUE}''${NC}"
echo
}
show_main_menu() {
show_header
echo -e "''${WHITE}🎛 Main Menu''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 📦 System Management"
echo -e "''${GREEN}2.''${NC} 🎨 Theme & Appearance"
echo -e "''${GREEN}3.''${NC} Configuration"
echo -e "''${GREEN}4.''${NC} 🔧 Development Tools"
echo -e "''${GREEN}5.''${NC} 📊 System Information"
echo -e "''${GREEN}6.''${NC} 🛠 Maintenance & Utilities"
echo -e "''${GREEN}7.''${NC} 📋 Help & Documentation"
echo
echo -e "''${RED}0.''${NC} Exit"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
show_system_menu() {
show_header
echo -e "''${WHITE}📦 System Management''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 🔄 Update System"
echo -e "''${GREEN}2.''${NC} 🔨 Rebuild Configuration"
echo -e "''${GREEN}3.''${NC} 🧪 Test Configuration"
echo -e "''${GREEN}4.''${NC} 🧹 Clean System"
echo -e "''${GREEN}5.''${NC} 📊 Service Status"
echo -e "''${GREEN}6.''${NC} 💾 Create Backup"
echo -e "''${GREEN}7.''${NC} 🔍 Search Packages"
echo
echo -e "''${YELLOW}8.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
show_theme_menu() {
show_header
echo -e "''${WHITE}🎨 Theme & Appearance''${NC}"
echo
echo -e "''${WHITE}Current Theme: ''${YELLOW}${cfg.theme}''${NC}"
echo
echo -e "''${GREEN}Available Themes:''${NC}"
echo -e "''${GREEN}1.''${NC} 🌃 tokyo-night - Dark theme with vibrant colors"
echo -e "''${GREEN}2.''${NC} 🎀 catppuccin - Pastel theme with modern aesthetics"
echo -e "''${GREEN}3.''${NC} 🟤 gruvbox - Retro theme with warm colors"
echo -e "''${GREEN}4.''${NC} nord - Arctic theme with cool colors"
echo -e "''${GREEN}5.''${NC} 🌲 everforest - Green forest theme"
echo -e "''${GREEN}6.''${NC} 🌹 rose-pine - Cozy theme with muted colors"
echo -e "''${GREEN}7.''${NC} 🌊 kanagawa - Japanese-inspired theme"
echo -e "''${GREEN}8.''${NC} catppuccin-latte - Light catppuccin variant"
echo -e "''${GREEN}9.''${NC} matte-black - Minimalist dark theme"
echo -e "''${GREEN}a.''${NC} 💎 osaka-jade - Jade green accent theme"
echo -e "''${GREEN}b.''${NC} ristretto - Coffee-inspired warm theme"
echo
echo -e "''${YELLOW}0.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select theme or option: ''${NC}"
}
show_config_menu() {
show_header
echo -e "''${WHITE} Configuration''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 📝 Edit Main Configuration"
echo -e "''${GREEN}2.''${NC} 🪟 Edit Hyprland Configuration"
echo -e "''${GREEN}3.''${NC} 🎨 Edit Theme Configuration"
echo -e "''${GREEN}4.''${NC} 📦 Edit Package Configuration"
echo -e "''${GREEN}5.''${NC} 🔒 Security Settings"
echo -e "''${GREEN}6.''${NC} 📂 Open Configuration Directory"
echo -e "''${GREEN}7.''${NC} 🔗 View Git Status"
echo
echo -e "''${YELLOW}0.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
show_dev_menu() {
show_header
echo -e "''${WHITE}🔧 Development Tools''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 💻 Open Terminal"
echo -e "''${GREEN}2.''${NC} 📝 Open Code Editor"
echo -e "''${GREEN}3.''${NC} 🌐 Open Browser"
echo -e "''${GREEN}4.''${NC} 📁 Open File Manager"
echo -e "''${GREEN}5.''${NC} 🚀 Launch Applications"
echo -e "''${GREEN}6.''${NC} 🐙 Git Operations"
echo
echo -e "''${YELLOW}0.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
show_info_menu() {
show_header
echo -e "''${WHITE}📊 System Information''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 🖥 System Overview"
echo -e "''${GREEN}2.''${NC} 💻 Hardware Information"
echo -e "''${GREEN}3.''${NC} 📈 Performance Monitor"
echo -e "''${GREEN}4.''${NC} 🔧 Service Status"
echo -e "''${GREEN}5.''${NC} 💾 Disk Usage"
echo -e "''${GREEN}6.''${NC} 🌐 Network Information"
echo -e "''${GREEN}7.''${NC} 📊 Omnixient About"
echo
echo -e "''${YELLOW}0.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
show_maintenance_menu() {
show_header
echo -e "''${WHITE}🛠 Maintenance & Utilities''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 🧹 System Cleanup"
echo -e "''${GREEN}2.''${NC} 🔄 Restart Services"
echo -e "''${GREEN}3.''${NC} 📋 View Logs"
echo -e "''${GREEN}4.''${NC} 💾 Backup Configuration"
echo -e "''${GREEN}5.''${NC} 🔧 System Diagnostics"
echo -e "''${GREEN}6.''${NC} 🖼 Screenshot Tools"
echo
echo -e "''${YELLOW}0.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
show_help_menu() {
show_header
echo -e "''${WHITE}📋 Help & Documentation''${NC}"
echo
echo -e "''${GREEN}1.''${NC} 📖 Omnixient Commands"
echo -e "''${GREEN}2.''${NC} 🔑 Keyboard Shortcuts"
echo -e "''${GREEN}3.''${NC} 🌐 Open GitHub Repository"
echo -e "''${GREEN}4.''${NC} 📧 Report Issue"
echo -e "''${GREEN}5.''${NC} About Omnixient"
echo
echo -e "''${YELLOW}0.''${NC} Back to Main Menu"
echo
echo -ne "''${CYAN}Select an option: ''${NC}"
}
handle_system_menu() {
case "$1" in
1) echo -e "''${GREEN}Updating system...''${NC}"; omni-update ;;
2) echo -e "''${GREEN}Rebuilding configuration...''${NC}"; omni-rebuild ;;
3) echo -e "''${GREEN}Testing configuration...''${NC}"; omni-test ;;
4) echo -e "''${GREEN}Cleaning system...''${NC}"; omni-clean ;;
5) echo -e "''${GREEN}Checking service status...''${NC}"; omni-services status ;;
6) echo -e "''${GREEN}Creating backup...''${NC}"; omni-backup ;;
7)
echo -ne "''${CYAN}Enter package name to search: ''${NC}"
read -r package
if [ -n "$package" ]; then
omni-search "$package"
fi
;;
8) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
handle_theme_menu() {
case "$1" in
1) omni-theme tokyo-night ;;
2) omni-theme catppuccin ;;
3) omni-theme gruvbox ;;
4) omni-theme nord ;;
5) omni-theme everforest ;;
6) omni-theme rose-pine ;;
7) omni-theme kanagawa ;;
8) omni-theme catppuccin-latte ;;
9) omni-theme matte-black ;;
a|A) omni-theme osaka-jade ;;
b|B) omni-theme ristretto ;;
0) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
handle_config_menu() {
case "$1" in
1) omni-config main ;;
2) omni-config hyprland ;;
3) omni-config theme ;;
4) omni-config packages ;;
5)
echo -e "''${CYAN}Security Settings:''${NC}"
echo -e "''${WHITE}1. Security Status 2. Fingerprint Setup 3. FIDO2 Setup''${NC}"
echo -ne "''${CYAN}Select: ''${NC}"
read -r security_choice
case "$security_choice" in
1) omni-security status ;;
2) omni-fingerprint setup ;;
3) omni-fido2 setup ;;
esac
;;
6) cd /etc/nixos && ''${TERMINAL:-ghostty} ;;
7) cd /etc/nixos && git status ;;
0) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
handle_dev_menu() {
case "$1" in
1) ''${TERMINAL:-ghostty} ;;
2) code ;;
3) ''${BROWSER:-firefox} ;;
4) thunar ;;
5) walker ;;
6)
echo -e "''${CYAN}Git Operations:''${NC}"
echo -e "''${WHITE}1. Status 2. Log 3. Commit 4. Push''${NC}"
echo -ne "''${CYAN}Select: ''${NC}"
read -r git_choice
cd /etc/nixos
case "$git_choice" in
1) git status ;;
2) git log --oneline -10 ;;
3) echo -ne "''${CYAN}Commit message: ''${NC}"; read -r msg; git add -A && git commit -m "$msg" ;;
4) git push ;;
esac
;;
0) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
handle_info_menu() {
case "$1" in
1) omni-sysinfo ;;
2) omni-hardware ;;
3) htop ;;
4) omni-services status ;;
5) df -h && echo && du -sh /nix/store ;;
6) ip addr show ;;
7) omni-about ;;
0) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
handle_maintenance_menu() {
case "$1" in
1) omni-clean ;;
2)
echo -ne "''${CYAN}Enter service name: ''${NC}"
read -r service
if [ -n "$service" ]; then
omni-services restart "$service"
fi
;;
3)
echo -ne "''${CYAN}Enter service name for logs: ''${NC}"
read -r service
if [ -n "$service" ]; then
omni-services logs "$service"
fi
;;
4) omni-backup ;;
5) echo -e "''${GREEN}Running diagnostics...''${NC}"; journalctl -p 3 -xb ;;
6) grim -g "$(slurp)" - | satty -f - --output-filename ~/Pictures/Screenshots/screenshot_$(date +'%Y-%m-%d-%H%M%S.png') ;;
0) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
handle_help_menu() {
case "$1" in
1)
echo -e "''${WHITE}Omnixient Commands:''${NC}"
echo -e "''${GREEN}omni-menu''${NC} - This interactive menu"
echo -e "''${GREEN}omni-info''${NC} - System information display"
echo -e "''${GREEN}omni-about''${NC} - About screen"
echo -e "''${GREEN}omni-theme''${NC} - Switch themes"
echo -e "''${GREEN}omni-rebuild''${NC} - Rebuild configuration"
echo -e "''${GREEN}omni-update''${NC} - Update system"
echo -e "''${GREEN}omni-clean''${NC} - Clean system"
echo -e "''${GREEN}omni-search''${NC} - Search packages"
;;
2)
echo -e "''${WHITE}Hyprland Keyboard Shortcuts:''${NC}"
echo -e "''${GREEN}Super + Return''${NC} - Open terminal"
echo -e "''${GREEN}Super + R''${NC} - Open launcher"
echo -e "''${GREEN}Super + Q''${NC} - Close window"
echo -e "''${GREEN}Super + F''${NC} - Fullscreen"
echo -e "''${GREEN}Super + 1-0''${NC} - Switch workspaces"
;;
3) ''${BROWSER:-firefox} https://github.com/TheArctesian/omnixy ;;
4) ''${BROWSER:-firefox} https://github.com/TheArctesian/omnixy/issues ;;
5) omni-about ;;
0) return 0 ;;
*) echo -e "''${RED}Invalid option!''${NC}" ;;
esac
echo
echo -ne "''${YELLOW}Press Enter to continue...''${NC}"
read -r
}
# Main menu loop
while true; do
show_main_menu
read -r choice
case "$choice" in
1)
while true; do
show_system_menu
read -r sub_choice
handle_system_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
2)
while true; do
show_theme_menu
read -r sub_choice
handle_theme_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
3)
while true; do
show_config_menu
read -r sub_choice
handle_config_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
4)
while true; do
show_dev_menu
read -r sub_choice
handle_dev_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
5)
while true; do
show_info_menu
read -r sub_choice
handle_info_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
6)
while true; do
show_maintenance_menu
read -r sub_choice
handle_maintenance_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
7)
while true; do
show_help_menu
read -r sub_choice
handle_help_menu "$sub_choice"
[ "$?" -eq 0 ] && break
done
;;
0|q|Q)
echo -e "''${GREEN}Goodbye! 👋''${NC}"
exit 0
;;
*)
echo -e "''${RED}Invalid option! Press Enter to continue...''${NC}"
read -r
;;
esac
done
'')
# Quick theme selector
(omni.makeScript "omni-theme-picker" "Quick theme picker with preview" ''
#!/bin/bash
# Colors
CYAN='\033[0;36m'
WHITE='\033[1;37m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
themes=(
"tokyo-night:🌃:Dark theme with vibrant colors"
"catppuccin:🎀:Pastel theme with modern aesthetics"
"gruvbox:🟤:Retro theme with warm colors"
"nord: :Arctic theme with cool colors"
"everforest:🌲:Green forest theme"
"rose-pine:🌹:Cozy theme with muted colors"
"kanagawa:🌊:Japanese-inspired theme"
"catppuccin-latte: :Light catppuccin variant"
"matte-black::Minimalist dark theme"
"osaka-jade:💎:Jade green accent theme"
"ristretto::Coffee-inspired warm theme"
)
clear
echo -e "''${CYAN}🎨 Omnixient Theme Picker''${NC}"
echo -e "''${WHITE}Current Theme: ''${YELLOW}${cfg.theme}''${NC}"
echo
echo -e "''${WHITE}Available Themes:''${NC}"
echo
for i in "''${!themes[@]}"; do
IFS=':' read -ra theme_info <<< "''${themes[$i]}"
theme_name="''${theme_info[0]}"
theme_icon="''${theme_info[1]}"
theme_desc="''${theme_info[2]}"
printf "''${GREEN}%2d.''${NC} %s %-15s - %s\n" "$((i+1))" "$theme_icon" "$theme_name" "$theme_desc"
done
echo
echo -e "''${RED} 0.''${NC} Cancel"
echo
echo -ne "''${CYAN}Select theme (1-''${#themes[@]}): ''${NC}"
read -r choice
if [[ "$choice" -ge 1 && "$choice" -le "''${#themes[@]}" ]]; then
IFS=':' read -ra theme_info <<< "''${themes[$((choice-1))]}"
selected_theme="''${theme_info[0]}"
echo -e "''${GREEN}Switching to ''${selected_theme}...''${NC}"
omni-theme "$selected_theme"
elif [[ "$choice" == "0" ]]; then
echo -e "''${YELLOW}Cancelled.''${NC}"
else
echo -e "''${RED}Invalid selection!''${NC}"
exit 1
fi
'')
];
# Shell aliases for easy access
home-manager.users.${config.omni.user} = {
programs.bash.shellAliases = {
menu = "omni-menu";
themes = "omni-theme-picker";
rebuild = mkDefault "omni-rebuild";
update = mkDefault "omni-update";
info = "omni-info";
clean = mkDefault "omni-clean";
};
programs.zsh.shellAliases = {
menu = "omni-menu";
themes = "omni-theme-picker";
rebuild = mkDefault "omni-rebuild";
update = mkDefault "omni-update";
info = "omni-info";
clean = mkDefault "omni-clean";
};
programs.fish.shellAliases = {
menu = "omni-menu";
themes = "omni-theme-picker";
rebuild = mkDefault "omni-rebuild";
update = mkDefault "omni-update";
info = "omni-info";
clean = mkDefault "omni-clean";
};
};
};
}

540
modules/partitioning.sh Executable file
View file

@ -0,0 +1,540 @@
#!/usr/bin/env bash
# Omnixient Disk Partitioning Module
# Comprehensive partitioning with LUKS encryption support
# Follows NixOS Installation Guide recommendations
set -e
# Color setup for output
setup_colors() {
RED=$(printf '\033[38;2;247;118;142m')
GREEN=$(printf '\033[38;2;158;206;106m')
YELLOW=$(printf '\033[38;2;224;175;104m')
CYAN=$(printf '\033[38;2;125;207;255m')
BLUE=$(printf '\033[38;2;122;162;247m')
PURPLE=$(printf '\033[38;2;187;154;247m')
FG=$(printf '\033[38;2;192;202;245m')
BOLD=$(printf '\033[1m')
DIM=$(printf '\033[2m')
RESET=$(printf '\033[0m')
}
setup_colors
# Utility functions
log_info() {
echo -e "${CYAN}[INFO]${RESET} $1"
}
log_success() {
echo -e "${GREEN}[✓]${RESET} $1"
}
log_error() {
echo -e "${RED}[ERROR]${RESET} $1" >&2
}
log_warn() {
echo -e "${YELLOW}[WARN]${RESET} $1"
}
# VM Detection
detect_vm() {
if systemd-detect-virt >/dev/null 2>&1; then
local virt_type=$(systemd-detect-virt)
if [ "$virt_type" != "none" ]; then
log_info "Running in virtualized environment: $virt_type"
return 0
fi
fi
return 1
}
# List available disks
list_disks() {
log_info "Available disks:"
echo
lsblk -d -n -o NAME,SIZE,TYPE,MODEL | while read -r name size type model; do
# Include both sd* and vd* devices
if [[ "$name" =~ ^(sd|vd|nvme) ]]; then
echo " ${CYAN}/dev/$name${RESET} - $size - $model"
# Show existing partitions if any
lsblk /dev/$name -n -o NAME,SIZE,FSTYPE,MOUNTPOINT 2>/dev/null | tail -n +2 | while read -r part psize fstype mount; do
echo " └─ $part - $psize - ${fstype:-none} ${mount:+(mounted: $mount)}"
done
fi
done
echo
}
# Disk selection with VM support
select_disk() {
list_disks
local selected_disk=""
while [ -z "$selected_disk" ]; do
read -p "${CYAN}Enter disk device (e.g., /dev/sda, /dev/vda, /dev/nvme0n1): ${RESET}" disk_input
# Normalize input
if [[ ! "$disk_input" =~ ^/dev/ ]]; then
disk_input="/dev/$disk_input"
fi
# Validate disk exists
if [ -b "$disk_input" ]; then
# Confirm destructive operation
echo
log_warn "WARNING: All data on $disk_input will be destroyed!"
read -p "${YELLOW}Type 'yes' to confirm: ${RESET}" confirm
if [ "$confirm" = "yes" ]; then
selected_disk="$disk_input"
else
log_info "Disk selection cancelled"
fi
else
log_error "Device $disk_input does not exist or is not a block device"
fi
done
echo "$selected_disk"
}
# Partition scheme selection
select_partition_scheme() {
echo
log_info "Select partition scheme:"
echo " 1) Automatic - Standard layout with optional encryption"
echo " 2) Manual - Use existing partitions"
echo " 3) Custom - Interactive partitioning"
echo
local scheme=""
while [ -z "$scheme" ]; do
read -p "${CYAN}Choice (1-3): ${RESET}" choice
case $choice in
1) scheme="automatic";;
2) scheme="manual";;
3) scheme="custom";;
*) log_error "Invalid choice";;
esac
done
echo "$scheme"
}
# Detect boot mode (UEFI or BIOS)
detect_boot_mode() {
if [ -d /sys/firmware/efi/efivars ]; then
echo "uefi"
else
echo "bios"
fi
}
# Automatic partitioning with LUKS support
automatic_partition() {
local disk="$1"
local encrypt="${2:-false}"
local boot_mode=$(detect_boot_mode)
log_info "Starting automatic partitioning on $disk"
log_info "Boot mode: $boot_mode"
# Wipe disk
log_info "Wiping disk..."
wipefs -af "$disk" >/dev/null 2>&1
sgdisk -Z "$disk" >/dev/null 2>&1
# Create partition table
if [ "$boot_mode" = "uefi" ]; then
log_info "Creating GPT partition table..."
parted -s "$disk" mklabel gpt
# Create partitions
log_info "Creating EFI partition..."
parted -s "$disk" mkpart ESP fat32 1MiB 512MiB
parted -s "$disk" set 1 esp on
log_info "Creating boot partition..."
parted -s "$disk" mkpart primary ext4 512MiB 1GiB
log_info "Creating root partition..."
parted -s "$disk" mkpart primary 1GiB 100%
# Wait for kernel to recognize partitions
partprobe "$disk"
sleep 2
# Determine partition naming
if [[ "$disk" =~ nvme ]]; then
local efi_part="${disk}p1"
local boot_part="${disk}p2"
local root_part="${disk}p3"
else
local efi_part="${disk}1"
local boot_part="${disk}2"
local root_part="${disk}3"
fi
else
log_info "Creating MBR partition table..."
parted -s "$disk" mklabel msdos
log_info "Creating boot partition..."
parted -s "$disk" mkpart primary ext4 1MiB 512MiB
parted -s "$disk" set 1 boot on
log_info "Creating root partition..."
parted -s "$disk" mkpart primary 512MiB 100%
# Wait for kernel to recognize partitions
partprobe "$disk"
sleep 2
# Determine partition naming
if [[ "$disk" =~ nvme ]]; then
local boot_part="${disk}p1"
local root_part="${disk}p2"
else
local boot_part="${disk}1"
local root_part="${disk}2"
fi
fi
# Setup encryption if requested
if [ "$encrypt" = "true" ]; then
log_info "Setting up LUKS encryption..."
# Get passphrase
local passphrase=""
local passphrase_confirm=""
while true; do
read -s -p "${CYAN}Enter LUKS passphrase: ${RESET}" passphrase
echo
read -s -p "${CYAN}Confirm passphrase: ${RESET}" passphrase_confirm
echo
if [ "$passphrase" = "$passphrase_confirm" ]; then
if [ ${#passphrase} -ge 8 ]; then
break
else
log_error "Passphrase must be at least 8 characters"
fi
else
log_error "Passphrases do not match"
fi
done
# Encrypt root partition
log_info "Encrypting root partition..."
echo -n "$passphrase" | cryptsetup luksFormat --type luks2 "$root_part" -
log_info "Opening encrypted partition..."
echo -n "$passphrase" | cryptsetup open "$root_part" cryptroot -
# Update root partition reference
root_part="/dev/mapper/cryptroot"
fi
# Format partitions
log_info "Formatting partitions..."
if [ "$boot_mode" = "uefi" ]; then
mkfs.fat -F32 -n ESP "$efi_part"
mkfs.ext4 -L boot "$boot_part"
else
mkfs.ext4 -L boot "$boot_part"
fi
# Format root - offer filesystem choice
echo
log_info "Select root filesystem:"
echo " 1) ext4 (recommended, stable)"
echo " 2) btrfs (snapshots, compression)"
echo " 3) zfs (advanced features, requires setup)"
echo
local fs_type="ext4"
read -p "${CYAN}Choice (1-3) [default: 1]: ${RESET}" fs_choice
case $fs_choice in
2) fs_type="btrfs";;
3) fs_type="zfs";;
*) fs_type="ext4";;
esac
case $fs_type in
ext4)
mkfs.ext4 -L nixos "$root_part"
;;
btrfs)
mkfs.btrfs -L nixos "$root_part"
;;
zfs)
log_warn "ZFS requires additional setup"
# Create ZFS pool
zpool create -f -o ashift=12 -O compression=lz4 -O xattr=sa -O acltype=posixacl -O mountpoint=none rpool "$root_part"
zfs create -o mountpoint=legacy rpool/root
zfs create -o mountpoint=legacy rpool/home
;;
esac
# Mount partitions
log_info "Mounting partitions..."
# Mount root
if [ "$fs_type" = "zfs" ]; then
mount -t zfs rpool/root /mnt
mkdir -p /mnt/home
mount -t zfs rpool/home /mnt/home
else
mount "$root_part" /mnt
fi
# Mount boot
mkdir -p /mnt/boot
mount "$boot_part" /mnt/boot
# Mount EFI if UEFI
if [ "$boot_mode" = "uefi" ]; then
mkdir -p /mnt/boot/efi
mount "$efi_part" /mnt/boot/efi
fi
# Create swap file
log_info "Creating swap file..."
local ram_size=$(free -g | awk '/^Mem:/{print $2}')
local swap_size=$((ram_size < 8 ? ram_size * 2 : ram_size))
if [ "$fs_type" = "btrfs" ]; then
# Btrfs requires special handling for swap
btrfs subvolume create /mnt/swap
truncate -s 0 /mnt/swap/swapfile
chattr +C /mnt/swap/swapfile
fallocate -l ${swap_size}G /mnt/swap/swapfile
else
fallocate -l ${swap_size}G /mnt/swapfile
fi
chmod 600 /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile
log_success "Automatic partitioning complete"
# Return partition information
cat <<EOF
PARTITION_INFO
DISK=$disk
BOOT_MODE=$boot_mode
ROOT_PART=$root_part
BOOT_PART=$boot_part
${boot_mode:+EFI_PART=$efi_part}
FS_TYPE=$fs_type
ENCRYPTED=$encrypt
EOF
}
# Manual partition selection
manual_partition() {
log_info "Manual partition selection"
echo
log_info "Available partitions:"
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
echo
# Get root partition
local root_part=""
while [ -z "$root_part" ]; do
read -p "${CYAN}Enter root partition (e.g., /dev/sda2): ${RESET}" root_part
if [ ! -b "$root_part" ]; then
log_error "Partition $root_part does not exist"
root_part=""
fi
done
# Check if encrypted
local encrypted="false"
if cryptsetup isLuks "$root_part" 2>/dev/null; then
log_info "Detected LUKS encrypted partition"
encrypted="true"
read -s -p "${CYAN}Enter passphrase: ${RESET}" passphrase
echo
echo -n "$passphrase" | cryptsetup open "$root_part" cryptroot -
root_part="/dev/mapper/cryptroot"
fi
# Get boot partition
local boot_part=""
read -p "${CYAN}Enter boot partition (leave empty if combined with root): ${RESET}" boot_part
# Get EFI partition if UEFI
local efi_part=""
if [ "$(detect_boot_mode)" = "uefi" ]; then
read -p "${CYAN}Enter EFI partition: ${RESET}" efi_part
if [ ! -b "$efi_part" ]; then
log_error "EFI partition required for UEFI systems"
exit 1
fi
fi
# Mount partitions
log_info "Mounting partitions..."
mount "$root_part" /mnt
if [ -n "$boot_part" ]; then
mkdir -p /mnt/boot
mount "$boot_part" /mnt/boot
fi
if [ -n "$efi_part" ]; then
mkdir -p /mnt/boot/efi
mount "$efi_part" /mnt/boot/efi
fi
log_success "Manual partition setup complete"
}
# Custom interactive partitioning
custom_partition() {
local disk="$1"
log_info "Starting custom partitioning with gdisk/fdisk"
log_warn "This will launch an interactive partitioning tool"
echo
echo "Guidelines:"
echo " - UEFI systems: Create EFI (512MB), boot (512MB), and root partitions"
echo " - BIOS systems: Create boot (512MB) and root partitions"
echo " - Consider leaving space for swap or using a swap file"
echo
read -p "${CYAN}Press Enter to continue...${RESET}"
# Launch appropriate tool
if command -v gdisk >/dev/null; then
gdisk "$disk"
elif command -v fdisk >/dev/null; then
fdisk "$disk"
else
log_error "No partitioning tool available"
exit 1
fi
# After partitioning, guide through formatting
log_info "Partitioning complete. Now format and mount partitions."
manual_partition
}
# Validate mount points
validate_mounts() {
log_info "Validating mount points..."
# Check root is mounted
if ! mountpoint -q /mnt; then
log_error "Root filesystem not mounted at /mnt"
return 1
fi
# Check boot for UEFI
if [ "$(detect_boot_mode)" = "uefi" ]; then
if ! mountpoint -q /mnt/boot/efi && ! mountpoint -q /mnt/boot; then
log_error "EFI partition not mounted"
return 1
fi
fi
log_success "Mount points validated"
return 0
}
# Generate hardware configuration
generate_hardware_config() {
log_info "Generating NixOS hardware configuration..."
nixos-generate-config --root /mnt
log_success "Hardware configuration generated"
}
# Main partitioning flow
main() {
echo
log_info "${BOLD}Omnixient Disk Partitioning Module${RESET}"
echo
# Check if running as root
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run as root"
exit 1
fi
# Detect VM environment
if detect_vm; then
log_info "VM environment detected - looking for vda devices"
fi
# Check if already mounted
if mountpoint -q /mnt; then
log_warn "/mnt is already mounted"
read -p "${YELLOW}Unmount and continue? (y/N): ${RESET}" unmount
if [ "$unmount" = "y" ]; then
umount -R /mnt 2>/dev/null || true
swapoff -a 2>/dev/null || true
else
log_info "Using existing mount points"
validate_mounts && generate_hardware_config
exit 0
fi
fi
# Select partitioning method
local scheme=$(select_partition_scheme)
case $scheme in
automatic)
local disk=$(select_disk)
# Ask about encryption
local encrypt="false"
read -p "${CYAN}Enable LUKS encryption? (y/N): ${RESET}" use_encryption
if [ "$use_encryption" = "y" ]; then
encrypt="true"
fi
automatic_partition "$disk" "$encrypt"
;;
manual)
manual_partition
;;
custom)
local disk=$(select_disk)
custom_partition "$disk"
;;
esac
# Validate and generate config
if validate_mounts; then
generate_hardware_config
echo
log_success "${BOLD}Partitioning complete!${RESET}"
echo
log_info "Next steps:"
echo " 1. Install Omnixient configuration to /mnt/etc/nixos"
echo " 2. Run nixos-install"
echo " 3. Set root password when prompted"
echo " 4. Reboot into your new system"
echo
# Save partition info for installer
if [ -n "$PARTITION_INFO" ]; then
echo "$PARTITION_INFO" > /tmp/omni-partition-info
log_info "Partition information saved to /tmp/omni-partition-info"
fi
else
log_error "Mount validation failed"
exit 1
fi
}
# Run if executed directly
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
main "$@"
fi

373
modules/scripts.nix Normal file
View file

@ -0,0 +1,373 @@
{
config,
pkgs,
lib,
...
}:
# Essential system utility scripts for Omnixient
# Convenient scripts for system management and productivity
let
inherit (lib) mkIf;
cfg = config.omni;
omni = config.omni.lib;
in
{
config = mkIf (cfg.enable or true) {
# System utility scripts
environment.systemPackages = [
# System information and monitoring
(omni.makeScript "omni-sysinfo" "Show comprehensive system information" ''
echo " Omnixient System Info "
echo ""
echo " 💻 System: $(hostname) ($(uname -m))"
echo " 🐧 OS: NixOS $(nixos-version)"
echo " 🎨 Theme: ${cfg.theme}"
echo " 👤 User: ${cfg.user}"
echo " 🏠 Preset: ${cfg.preset or "custom"}"
echo ""
echo " 🔧 Uptime: $(uptime -p)"
echo " 💾 Memory: $(free -h | awk 'NR==2{printf "%.1f/%.1fGB (%.0f%%)", $3/1024/1024, $2/1024/1024, $3*100/$2}')"
echo " 💽 Disk: $(df -h / | awk 'NR==2{printf "%s/%s (%s)", $3, $2, $5}')"
echo " 🌡 Load: $(uptime | sed 's/.*load average: //')"
echo ""
echo " 📦 Packages: $(nix-env -qa --installed | wc -l) installed"
echo " 🗂 Generations: $(sudo nix-env -p /nix/var/nix/profiles/system --list-generations | wc -l) total"
echo ""
echo ""
'')
# Quick system maintenance
(omni.makeScript "omni-clean" "Clean system (garbage collect, optimize)" ''
echo "🧹 Cleaning Omnixient system..."
echo " Collecting garbage..."
sudo nix-collect-garbage -d
echo " Optimizing store..."
sudo nix-store --optimize
echo " Clearing user caches..."
rm -rf ~/.cache/thumbnails/*
rm -rf ~/.cache/mesa_shader_cache/*
rm -rf ~/.cache/fontconfig/*
echo " Clearing logs..."
sudo journalctl --vacuum-time=7d
echo " Cleaning complete!"
# Show space saved
echo
echo "💾 Disk usage:"
df -h / | awk 'NR==2{printf " Root: %s/%s (%s used)\n", $3, $2, $5}'
du -sh /nix/store | awk '{printf " Nix Store: %s\n", $1}'
'')
# Update system and flake
(omni.makeScript "omni-update" "Update system and flake inputs" ''
echo "📦 Updating Omnixient system..."
cd /etc/nixos || { echo " Not in /etc/nixos directory"; exit 1; }
echo " Updating flake inputs..."
sudo nix flake update
echo " Rebuilding system..."
nh os switch /etc/nixos
echo " Update complete!"
# Show new generation
echo
echo "🎯 Current generation:"
sudo nix-env -p /nix/var/nix/profiles/system --list-generations | tail -1
'')
# Rebuild system configuration
(omni.makeScript "omni-rebuild" "Rebuild NixOS configuration" ''
echo "🔨 Rebuilding Omnixient configuration..."
cd /etc/nixos || { echo " Not in /etc/nixos directory"; exit 1; }
# Pull latest changes if the tree is clean
if git diff --quiet && git diff --cached --quiet; then
echo "📥 Pulling latest changes..."
sudo git pull --ff-only || echo " Pull failed continuing with local config"
else
echo " Uncommitted changes skipping pull"
echo " Commit or stash them to pull on next rebuild"
echo
fi
# Build and switch via nh (Rust nixos-rebuild frontend; elevates itself)
nh os switch /etc/nixos
if [ $? -eq 0 ]; then
echo " Rebuild successful!"
echo "🎯 Active generation: $(sudo nix-env -p /nix/var/nix/profiles/system --list-generations | tail -1)"
else
echo " Rebuild failed!"
exit 1
fi
'')
# Test build without switching
(omni.makeScript "omni-test" "Test build configuration without switching" ''
echo "🧪 Testing Omnixient configuration..."
cd /etc/nixos || { echo " Not in /etc/nixos directory"; exit 1; }
# Build without switching
sudo nixos-rebuild build --flake .#omni
if [ $? -eq 0 ]; then
echo " Build test successful!"
echo " Configuration is valid and ready for deployment"
else
echo " Build test failed!"
echo " Fix configuration errors before rebuilding"
exit 1
fi
'')
# Search for packages
(omni.makeScript "omni-search" "Search for NixOS packages" ''
if [ -z "$1" ]; then
echo "Usage: omni-search <package-name>"
echo "Search for packages in nixpkgs"
exit 1
fi
echo "🔍 Searching for packages matching '$1'..."
echo
# Search in nixpkgs
nix search nixpkgs "$1" | head -20
echo
echo "💡 Install with: nix-env -iA nixpkgs.<package>"
echo " Or add to your configuration.nix"
'')
# Theme management
(omni.makeScript "omni-theme" "Switch Omnixient theme" ''
if [ -z "$1" ]; then
echo "🎨 Available Omnixient themes:"
echo " tokyo-night - Dark theme with vibrant colors"
echo " catppuccin - Pastel theme with modern aesthetics"
echo " gruvbox - Retro theme with warm colors"
echo " nord - Arctic theme with cool colors"
echo " everforest - Green forest theme"
echo " rose-pine - Cozy theme with muted colors"
echo " kanagawa - Japanese-inspired theme"
echo " catppuccin-latte - Light catppuccin variant"
echo " matte-black - Minimalist dark theme"
echo " osaka-jade - Jade green accent theme"
echo " ristretto - Coffee-inspired warm theme"
echo
echo "Usage: omni-theme <theme-name>"
echo "Current theme: ${cfg.theme}"
exit 0
fi
THEME="$1"
CONFIG_FILE="/etc/nixos/configuration.nix"
echo "🎨 Switching to theme: $THEME"
# Validate theme exists
if [ ! -f "/etc/nixos/modules/themes/$THEME.nix" ]; then
echo " Theme '$THEME' not found!"
echo " Available themes listed above"
exit 1
fi
# Update configuration.nix
sudo sed -i "s/currentTheme = \".*\";/currentTheme = \"$THEME\";/" "$CONFIG_FILE"
echo " Updated configuration..."
echo " Rebuilding system..."
# Rebuild with new theme
cd /etc/nixos && nh os switch /etc/nixos
if [ $? -eq 0 ]; then
echo " Theme switched successfully!"
echo " Updating Plymouth boot theme..."
# Update Plymouth theme to match
sudo omni-plymouth-theme "$THEME" 2>/dev/null || echo " (Plymouth theme update may require reboot)"
echo " Now using theme: $THEME"
echo "💡 Reboot to see the new boot splash screen"
else
echo " Failed to apply theme!"
# Revert change
sudo sed -i "s/currentTheme = \"$THEME\";/currentTheme = \"${cfg.theme}\";/" "$CONFIG_FILE"
exit 1
fi
'')
# Hardware information
(omni.makeScript "omni-hardware" "Show detailed hardware information" ''
echo "🖥 Omnixient Hardware Information"
echo ""
echo
echo "💻 System:"
echo " Model: $(cat /sys/class/dmi/id/product_name 2>/dev/null || echo 'Unknown')"
echo " Manufacturer: $(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || echo 'Unknown')"
echo " BIOS: $(cat /sys/class/dmi/id/bios_version 2>/dev/null || echo 'Unknown')"
echo
echo "🧠 CPU:"
lscpu | grep -E "Model name|Architecture|CPU\(s\)|Thread|Core|MHz"
echo
echo "💾 Memory:"
free -h
echo
echo "💽 Storage:"
lsblk -f
echo
echo "📺 Graphics:"
lspci | grep -i vga
lspci | grep -i 3d
echo
echo "🔊 Audio:"
lspci | grep -i audio
echo
echo "🌐 Network:"
ip addr show | grep -E "inet |link/"
'')
# Service management
(omni.makeScript "omni-services" "Manage Omnixient services" ''
case "$1" in
"status")
echo "📊 Omnixient Service Status"
echo ""
services=(
"display-manager"
"networkmanager"
"pipewire"
"bluetooth"
"hypridle"
)
for service in "''${services[@]}"; do
status=$(systemctl is-active $service 2>/dev/null || echo "inactive")
case $status in
"active") icon="" ;;
"inactive") icon="" ;;
*) icon=" " ;;
esac
printf " %s %s: %s\n" "$icon" "$service" "$status"
done
;;
"restart")
if [ -z "$2" ]; then
echo "Usage: omni-services restart <service-name>"
exit 1
fi
echo "🔄 Restarting $2..."
sudo systemctl restart "$2"
;;
"logs")
if [ -z "$2" ]; then
echo "Usage: omni-services logs <service-name>"
exit 1
fi
journalctl -u "$2" -f
;;
*)
echo "📋 Omnixient Service Management"
echo
echo "Usage: omni-services <command> [service]"
echo
echo "Commands:"
echo " status - Show status of key services"
echo " restart <name> - Restart a service"
echo " logs <name> - View service logs"
;;
esac
'')
# Quick configuration editing
(omni.makeScript "omni-config" "Quick access to configuration files" ''
case "$1" in
"main"|"")
echo "📝 Opening main configuration..."
''${EDITOR:-nano} /etc/nixos/configuration.nix
;;
"hyprland")
echo "📝 Opening Hyprland configuration..."
''${EDITOR:-nano} /etc/nixos/modules/desktop/hyprland.nix
;;
"theme")
echo "📝 Opening theme configuration..."
''${EDITOR:-nano} /etc/nixos/modules/themes/${cfg.theme}.nix
;;
"packages")
echo "📝 Opening package configuration..."
''${EDITOR:-nano} /etc/nixos/modules/packages.nix
;;
*)
echo "📝 Omnixient Configuration Files"
echo
echo "Usage: omni-config <target>"
echo
echo "Targets:"
echo " main - Main configuration.nix file"
echo " hyprland - Hyprland window manager config"
echo " theme - Current theme configuration"
echo " packages - Package configuration"
echo
echo "Files will open in: ''${EDITOR:-nano}"
;;
esac
'')
# Backup and restore
(omni.makeScript "omni-backup" "Backup Omnixient configuration" ''
BACKUP_DIR="$HOME/omni-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/omni_$TIMESTAMP.tar.gz"
echo "💾 Creating Omnixient configuration backup..."
mkdir -p "$BACKUP_DIR"
# Create backup archive
sudo tar -czf "$BACKUP_FILE" \
-C /etc \
nixos/ \
--exclude=nixos/hardware-configuration.nix
# Also backup user configs that matter
if [ -d "$HOME/.config" ]; then
tar -czf "$BACKUP_DIR/userconfig_$TIMESTAMP.tar.gz" \
-C "$HOME" \
.config/hypr/ \
.config/waybar/ \
.config/mako/ \
.config/walker/ 2>/dev/null || true
fi
echo " Backup created:"
echo " System: $BACKUP_FILE"
echo " User: $BACKUP_DIR/userconfig_$TIMESTAMP.tar.gz"
echo
echo "📊 Backup size:"
du -sh "$BACKUP_DIR"/*"$TIMESTAMP"* | sed 's/^/ /'
'')
];
};
}

124
modules/users.nix Normal file
View file

@ -0,0 +1,124 @@
{
config,
pkgs,
lib,
settings,
...
}:
let
cfg = config.omni;
in
{
# User account configuration
users.users.${cfg.user} = {
isNormalUser = true;
description = "Omnixient User";
extraGroups = [
"wheel"
"networkmanager"
"audio"
"video"
"docker"
"libvirtd"
"input"
"dialout"
];
shell = pkgs.bash;
# Set initial password (should be changed on first login)
# pragma: allowlist secret
initialPassword = "omni";
# SSH public keys authorized for this account — add yours in settings.nix.
openssh.authorizedKeys.keys = settings.sshKeys;
};
# Additional user-related configurations
users = {
# Allow users in wheel group to use sudo
mutableUsers = true;
# Default shell
defaultUserShell = pkgs.bash;
};
# Security settings for users
security.pam.services = {
# Enable fingerprint authentication
login.fprintAuth = false;
sudo.fprintAuth = false;
# Enable U2F authentication (for YubiKey etc.)
login.u2fAuth = false;
sudo.u2fAuth = false;
};
# Home directory encryption (optional)
# security.pam.enableEcryptfs = true;
# Automatic login (disable for production)
services.displayManager.autoLogin = {
enable = false;
user = cfg.user;
};
# User environment
environment.systemPackages = with pkgs; [
# User management tools
shadow # provides passwd, useradd, etc.
# Session management
systemd # provides loginctl
# User info
bsd-finger
idutils
];
# User-specific services
systemd.user.services = {
# Example: Syncthing for the user
# syncthing = {
# description = "Syncthing for ${cfg.user}";
# wantedBy = [ "default.target" ];
# serviceConfig = {
# ExecStart = "${pkgs.syncthing}/bin/syncthing serve --no-browser --no-restart --logflags=0";
# Restart = "on-failure";
# RestartSec = 10;
# };
# };
};
# Shell initialization for all users
programs.bash.interactiveShellInit = ''
# User-specific aliases
alias profile='nvim ~/.bashrc'
alias reload='source ~/.bashrc'
# Safety aliases
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Directory shortcuts
alias home='cd ~'
alias downloads='cd ~/Downloads'
alias documents='cd ~/Documents'
alias projects='cd ~/Projects'
# Create standard directories if they don't exist
mkdir -p ~/Downloads ~/Documents ~/Projects ~/Pictures ~/Videos ~/Music
'';
# XDG Base Directory specification
environment.variables = {
XDG_CACHE_HOME = "$HOME/.cache";
XDG_CONFIG_HOME = "$HOME/.config";
XDG_DATA_HOME = "$HOME/.local/share";
XDG_STATE_HOME = "$HOME/.local/state";
};
# User quotas (optional)
# fileSystems."/home".options = [ "usrquota" ];
}

450
modules/walker.nix Normal file
View file

@ -0,0 +1,450 @@
{
config,
pkgs,
lib,
...
}:
# Walker app launcher configuration for Omnixient
# Modern replacement for Rofi with better Wayland integration
let
inherit (lib) mkIf;
cfg = config.omni;
omni = {
makeScript =
name: description: script:
pkgs.writeShellScriptBin name ''
#!/usr/bin/env bash
# ${description}
set -euo pipefail
${script}
'';
};
in
{
config = mkIf (cfg.enable or true) {
# Add convenience scripts to system packages
environment.systemPackages = [
# Convenience scripts
(omni.makeScript "omni-launcher" "Launch Omnixient app launcher" ''
walker --config ~/.config/walker/config.json --css ~/.config/walker/themes/style.css
'')
(omni.makeScript "omni-run" "Quick command runner" ''
walker --modules runner --config ~/.config/walker/config.json --css ~/.config/walker/themes/style.css
'')
(omni.makeScript "omni-apps" "Application launcher" ''
walker --modules applications --config ~/.config/walker/config.json --css ~/.config/walker/themes/style.css
'')
(omni.makeScript "omni-files" "File finder" ''
walker --modules finder --config ~/.config/walker/config.json --css ~/.config/walker/themes/style.css
'')
];
# Create Walker configuration
environment.etc."omni/walker/config.json".text = builtins.toJSON {
# General configuration
placeholder = "Search applications, files, and more...";
fullscreen = false;
layer = "overlay";
modules = [
{
name = "applications";
src = "applications";
transform = "uppercase";
}
{
name = "runner";
src = "runner";
}
{
name = "websearch";
src = "websearch";
engines = [
{
name = "Google";
url = "https://www.google.com/search?q=%s";
icon = "web-browser";
}
{
name = "GitHub";
url = "https://github.com/search?q=%s";
icon = "github";
}
{
name = "NixOS Packages";
url = "https://search.nixos.org/packages?query=%s";
icon = "nix-snowflake";
}
];
}
{
name = "finder";
src = "finder";
dirs = [
"/home/${cfg.user}"
"/home/${cfg.user}/Documents"
"/home/${cfg.user}/Downloads"
"/home/${cfg.user}/Desktop"
];
}
{
name = "calc";
src = "calc";
}
];
# UI Configuration
ui = {
anchors = {
top = false;
left = true;
right = false;
bottom = false;
};
margin = {
top = 100;
bottom = 0;
left = 100;
right = 0;
};
width = 600;
height = 500;
show_initial_entries = true;
show_search_text = true;
scroll_height = 300;
};
# Search configuration
search = {
delay = 100;
placeholder = "Type to search...";
force_keyboard_focus = true;
};
# List configuration
list = {
height = 200;
always_show = true;
max_entries = 50;
};
# Icons
icons = {
theme = "Papirus";
size = 32;
};
# Theming based on current theme
theme =
if cfg.theme == "gruvbox" then
"gruvbox"
else if cfg.theme == "nord" then
"nord"
else if cfg.theme == "catppuccin" then
"catppuccin"
else if cfg.theme == "tokyo-night" then
"tokyo-night"
else
"default";
};
# Create Walker CSS theme files
environment.etc."omni/walker/themes/gruvbox.css".text = ''
* {
color: #ebdbb2;
font-family: "JetBrainsMono Nerd Font", monospace;
font-size: 14px;
}
#window {
background-color: rgba(40, 40, 40, 0.95);
}
window {
background-color: rgba(40, 40, 40, 0.95);
border: 2px solid #a89984;
border-radius: 12px;
}
box {
background-color: rgba(40, 40, 40, 0.95);
}
#search {
background-color: #3c3836;
border: 1px solid #665c54;
border-radius: 8px;
padding: 8px 12px;
margin: 12px;
color: #ebdbb2;
}
#search:focus {
border-color: #d79921;
}
#list {
background-color: rgba(40, 40, 40, 0.95);
padding: 0 12px 12px 12px;
}
.item {
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 2px;
}
.item:selected {
background-color: #504945;
color: #fbf1c7;
}
.item:hover {
background-color: #3c3836;
}
.item .icon {
margin-right: 12px;
min-width: 32px;
}
.item .text {
font-weight: normal;
}
.item .sub {
font-size: 12px;
color: #a89984;
}
'';
environment.etc."omni/walker/themes/nord.css".text = ''
* {
color: #eceff4;
background-color: #2e3440;
font-family: "JetBrainsMono Nerd Font", monospace;
font-size: 14px;
}
window {
background-color: rgba(46, 52, 64, 0.95);
border: 2px solid #4c566a;
border-radius: 12px;
}
#search {
background-color: #3b4252;
border: 1px solid #4c566a;
border-radius: 8px;
padding: 8px 12px;
margin: 12px;
color: #eceff4;
}
#search:focus {
border-color: #5e81ac;
}
#list {
background-color: transparent;
padding: 0 12px 12px 12px;
}
.item {
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 2px;
}
.item:selected {
background-color: #434c5e;
color: #eceff4;
}
.item:hover {
background-color: #3b4252;
}
.item .icon {
margin-right: 12px;
min-width: 32px;
}
.item .text {
font-weight: normal;
}
.item .sub {
font-size: 12px;
color: #81a1c1;
}
'';
environment.etc."omni/walker/themes/catppuccin.css".text = ''
* {
color: #cdd6f4;
background-color: #1e1e2e;
font-family: "JetBrainsMono Nerd Font", monospace;
font-size: 14px;
}
window {
background-color: rgba(30, 30, 46, 0.95);
border: 2px solid #6c7086;
border-radius: 12px;
}
#search {
background-color: #313244;
border: 1px solid #45475a;
border-radius: 8px;
padding: 8px 12px;
margin: 12px;
color: #cdd6f4;
}
#search:focus {
border-color: #89b4fa;
}
#list {
background-color: transparent;
padding: 0 12px 12px 12px;
}
.item {
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 2px;
}
.item:selected {
background-color: #45475a;
color: #cdd6f4;
}
.item:hover {
background-color: #313244;
}
.item .icon {
margin-right: 12px;
min-width: 32px;
}
.item .text {
font-weight: normal;
}
.item .sub {
font-size: 12px;
color: #89dceb;
}
'';
environment.etc."omni/walker/themes/tokyo-night.css".text = ''
* {
color: #c0caf5;
background-color: #1a1b26;
font-family: "JetBrainsMono Nerd Font", monospace;
font-size: 14px;
}
window {
background-color: rgba(26, 27, 38, 0.95);
border: 2px solid #414868;
border-radius: 12px;
}
#search {
background-color: #24283b;
border: 1px solid #414868;
border-radius: 8px;
padding: 8px 12px;
margin: 12px;
color: #c0caf5;
}
#search:focus {
border-color: #7aa2f7;
}
#list {
background-color: transparent;
padding: 0 12px 12px 12px;
}
.item {
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 2px;
}
.item:selected {
background-color: #414868;
color: #c0caf5;
}
.item:hover {
background-color: #24283b;
}
.item .icon {
margin-right: 12px;
min-width: 32px;
}
.item .text {
font-weight: normal;
}
.item .sub {
font-size: 12px;
color: #7dcfff;
}
'';
# Add to user environment
home-manager.users.${config.omni.user} = {
# Walker launcher via official home-manager module
programs.walker = {
enable = true;
runAsService = true;
};
# Walker config and theme CSS
xdg.configFile."walker/config.json".source =
config.environment.etc."omni/walker/config.json".source;
xdg.configFile."walker/themes/style.css".source =
config.environment.etc."omni/walker/themes/${cfg.theme}.css".source;
# Add shell aliases
programs.bash.shellAliases = {
launcher = "walker";
run = "walker --modules runner";
apps = "walker --modules applications";
files = "walker --modules finder";
};
programs.zsh.shellAliases = {
launcher = "walker";
run = "walker --modules runner";
apps = "walker --modules applications";
files = "walker --modules finder";
};
programs.fish.shellAliases = {
launcher = "walker";
run = "walker --modules runner";
apps = "walker --modules applications";
files = "walker --modules finder";
};
};
# Convenience scripts are now consolidated above
};
}