diff --git a/packages/forgejo-mcp.nix b/packages/forgejo-mcp.nix
new file mode 100644
index 0000000..7aec536
--- /dev/null
+++ b/packages/forgejo-mcp.nix
@@ -0,0 +1,42 @@
+# packages/forgejo-mcp.nix
+#
+# forgejo-mcp — Model Context Protocol server for Forgejo REST API.
+# Upstream: https://codeberg.org/goern/forgejo-mcp (de-facto community
+# implementation; no official forgejo/forgejo-mcp org repo exists yet).
+# Used by modules/mcp.nix as the forgejo-mcp server binary.
+{
+ lib,
+ buildGoModule,
+ fetchFromGitea,
+}:
+
+buildGoModule rec {
+ pname = "forgejo-mcp";
+ version = "2.17.0";
+
+ src = fetchFromGitea {
+ domain = "codeberg.org";
+ owner = "goern";
+ repo = "forgejo-mcp";
+ rev = "v${version}";
+ hash = "sha256-DcpS2467MCFfIVsdYEfd5t6kPjMeLElMQbDyuXI04XE=";
+ };
+
+ vendorHash = "sha256-5CV4drUaYKtZ/RoydAatblhsqU8VWYzYByjhcb9KZVY=";
+
+ subPackages = [ "." ];
+
+ ldflags = [
+ "-s"
+ "-w"
+ ];
+
+ doCheck = false;
+
+ meta = with lib; {
+ description = "Model Context Protocol server for Forgejo REST API";
+ homepage = "https://codeberg.org/goern/forgejo-mcp";
+ license = licenses.asl20;
+ mainProgram = "forgejo-mcp";
+ };
+}
diff --git a/packages/plymouth-theme.nix b/packages/plymouth-theme.nix
new file mode 100644
index 0000000..d3c3ccf
--- /dev/null
+++ b/packages/plymouth-theme.nix
@@ -0,0 +1,324 @@
+{
+ lib,
+ pkgs,
+ stdenv,
+ writeTextFile,
+ ...
+}:
+
+# Omnixient Plymouth Theme Package
+# Creates theme-aware Plymouth boot screens
+
+let
+ # Theme color definitions
+ themeColors = {
+ tokyo-night = {
+ bg = "#1a1b26";
+ fg = "#c0caf5";
+ accent = "#7aa2f7";
+ secondary = "#bb9af7";
+ };
+ catppuccin = {
+ bg = "#1e1e2e";
+ fg = "#cdd6f4";
+ accent = "#89b4fa";
+ secondary = "#cba6f7";
+ };
+ gruvbox = {
+ bg = "#282828";
+ fg = "#ebdbb2";
+ accent = "#d79921";
+ secondary = "#b16286";
+ };
+ nord = {
+ bg = "#2e3440";
+ fg = "#eceff4";
+ accent = "#5e81ac";
+ secondary = "#b48ead";
+ };
+ everforest = {
+ bg = "#2d353b";
+ fg = "#d3c6aa";
+ accent = "#a7c080";
+ secondary = "#e67e80";
+ };
+ rose-pine = {
+ bg = "#191724";
+ fg = "#e0def4";
+ accent = "#31748f";
+ secondary = "#c4a7e7";
+ };
+ kanagawa = {
+ bg = "#1f1f28";
+ fg = "#dcd7ba";
+ accent = "#7e9cd8";
+ secondary = "#957fb8";
+ };
+ catppuccin-latte = {
+ bg = "#eff1f5";
+ fg = "#4c4f69";
+ accent = "#1e66f5";
+ secondary = "#8839ef";
+ };
+ matte-black = {
+ bg = "#000000";
+ fg = "#ffffff";
+ accent = "#666666";
+ secondary = "#999999";
+ };
+ osaka-jade = {
+ bg = "#0d1b1e";
+ fg = "#c5d4d7";
+ accent = "#5fb3a1";
+ secondary = "#7ba05b";
+ };
+ ristretto = {
+ bg = "#2c1810";
+ fg = "#d4c5a7";
+ accent = "#d08b5b";
+ secondary = "#a67458";
+ };
+ };
+
+ # Base assets (copied from omarchy)
+ assets = pkgs.runCommand "omni-plymouth-assets" { } ''
+ mkdir -p $out
+
+ # Create base logo (Omnixient branding)
+ cat > $out/logo.svg <<'EOF'
+
+ EOF
+
+ # Convert SVG to PNG
+ ${pkgs.librsvg}/bin/rsvg-convert -w 120 -h 120 $out/logo.svg -o $out/logo.png
+ rm $out/logo.svg
+
+ # Create other UI elements (simplified versions of omarchy assets)
+ ${pkgs.imagemagick}/bin/convert -size 32x32 xc:none -fill '#ffffff' -draw 'circle 16,16 16,8' $out/lock.png
+ ${pkgs.imagemagick}/bin/convert -size 200x32 xc:'rgba(255,255,255,0.1)' -stroke white -strokewidth 1 -fill none -draw 'roundrectangle 1,1 198,30 8,8' $out/entry.png
+ ${pkgs.imagemagick}/bin/convert -size 8x8 xc:white $out/bullet.png
+ ${pkgs.imagemagick}/bin/convert -size 300x8 xc:'rgba(255,255,255,0.2)' -stroke white -strokewidth 1 -fill none -draw 'roundrectangle 1,1 298,6 4,4' $out/progress_box.png
+ ${pkgs.imagemagick}/bin/convert -size 296x4 xc:'rgba(255,255,255,0.8)' $out/progress_bar.png
+ '';
+
+ # Plymouth script template
+ createPlymouthScript =
+ themeName: colors:
+ writeTextFile {
+ name = "omni-${themeName}.script";
+ text = ''
+ # Omnixient Plymouth Theme Script
+ # Theme: ${themeName}
+ # Generated for NixOS/Omnixient
+
+ // Theme color configuration
+ bg_color = Colour("${colors.bg}");
+ fg_color = Colour("${colors.fg}");
+ accent_color = Colour("${colors.accent}");
+ secondary_color = Colour("${colors.secondary}");
+
+ // Screen setup
+ screen_width = Window.GetWidth();
+ screen_height = Window.GetHeight();
+ Window.SetBackgroundTopColor(bg_color);
+ Window.SetBackgroundBottomColor(bg_color);
+
+ // Load assets
+ logo_image = Image("logo.png");
+ lock_image = Image("lock.png");
+ entry_image = Image("entry.png");
+ bullet_image = Image("bullet.png");
+ progress_box_image = Image("progress_box.png");
+ progress_bar_image = Image("progress_bar.png");
+
+ // Logo setup
+ logo_sprite = Sprite(logo_image);
+ logo_sprite.SetX((screen_width - logo_image.GetWidth()) / 2);
+ logo_sprite.SetY(screen_height / 2 - 100);
+ logo_sprite.SetOpacity(0.9);
+
+ // Progress bar setup
+ progress_box_sprite = Sprite(progress_box_image);
+ progress_box_sprite.SetX((screen_width - progress_box_image.GetWidth()) / 2);
+ progress_box_sprite.SetY(screen_height / 2 + 50);
+
+ progress_bar_sprite = Sprite(progress_bar_image);
+ progress_bar_sprite.SetX((screen_width - progress_box_image.GetWidth()) / 2 + 2);
+ progress_bar_sprite.SetY(screen_height / 2 + 52);
+
+ // Animation variables
+ fake_progress = 0;
+ real_progress = 0;
+ start_time = Plymouth.GetTime();
+ fake_duration = 15; // 15 seconds fake progress
+
+ // Easing function (ease-out quadratic)
+ fun easeOutQuad(x) {
+ return 1 - (1 - x) * (1 - x);
+ }
+
+ // Progress update function
+ fun progress_callback() {
+ current_time = Plymouth.GetTime();
+ elapsed = current_time - start_time;
+
+ // Calculate fake progress (0 to 0.7 over fake_duration)
+ if (elapsed < fake_duration) {
+ fake_progress = 0.7 * easeOutQuad(elapsed / fake_duration);
+ } else {
+ fake_progress = 0.7;
+ }
+
+ // Use the maximum of fake and real progress
+ display_progress = fake_progress;
+ if (real_progress > fake_progress) {
+ display_progress = real_progress;
+ }
+
+ // Update progress bar
+ bar_width = progress_bar_image.GetWidth() * display_progress;
+ progress_bar_sprite.SetImage(progress_bar_image.Scale(bar_width, progress_bar_image.GetHeight()));
+
+ // Add subtle pulsing to logo during boot
+ pulse = Math.Sin(elapsed * 3) * 0.1 + 0.9;
+ logo_sprite.SetOpacity(pulse);
+ }
+
+ Plymouth.SetUpdateFunction(progress_callback);
+
+ // Boot progress callback
+ Plymouth.SetBootProgressFunction(
+ fun (duration, progress) {
+ real_progress = progress;
+ }
+ );
+
+ // Password dialog setup
+ question_sprite = Sprite();
+ answer_sprite = Sprite();
+
+ fun DisplayQuestionCallback(prompt, entry) {
+ question_sprite.SetImage(Image.Text(prompt, 1, 1, 1));
+ question_sprite.SetX((screen_width - question_sprite.GetImage().GetWidth()) / 2);
+ question_sprite.SetY(screen_height / 2 - 50);
+
+ // Show lock icon
+ lock_sprite = Sprite(lock_image);
+ lock_sprite.SetX((screen_width - lock_image.GetWidth()) / 2);
+ lock_sprite.SetY(screen_height / 2 - 20);
+
+ // Show entry field
+ entry_sprite = Sprite(entry_image);
+ entry_sprite.SetX((screen_width - entry_image.GetWidth()) / 2);
+ entry_sprite.SetY(screen_height / 2 + 20);
+
+ // Show bullets for password
+ bullet_sprites = [];
+ for (i = 0; i < entry.GetLength(); i++) {
+ bullet_sprites[i] = Sprite(bullet_image);
+ bullet_sprites[i].SetX((screen_width / 2) - (entry.GetLength() * 10 / 2) + i * 10);
+ bullet_sprites[i].SetY(screen_height / 2 + 28);
+ }
+ }
+
+ Plymouth.SetDisplayQuestionFunction(DisplayQuestionCallback);
+
+ // Hide question callback
+ Plymouth.SetDisplayPasswordFunction(DisplayQuestionCallback);
+
+ // Message display
+ message_sprite = Sprite();
+
+ Plymouth.SetMessageFunction(
+ fun (text) {
+ message_sprite.SetImage(Image.Text(text, 1, 1, 1));
+ message_sprite.SetX((screen_width - message_sprite.GetImage().GetWidth()) / 2);
+ message_sprite.SetY(screen_height - 50);
+ }
+ );
+
+ // Quit callback
+ Plymouth.SetQuitFunction(
+ fun () {
+ // Fade out animation
+ for (i = 0; i < 30; i++) {
+ opacity = 1 - (i / 30);
+ logo_sprite.SetOpacity(opacity);
+ Plymouth.Sleep(16); // ~60fps
+ }
+ }
+ );
+ '';
+ };
+
+ # Create theme definition file
+ createPlymouthTheme =
+ themeName: colors:
+ writeTextFile {
+ name = "omni-${themeName}.plymouth";
+ text = ''
+ [Plymouth Theme]
+ Name=Omnixient ${themeName}
+ Description=Omnixient boot splash theme for ${themeName}
+ ModuleName=script
+
+ [script]
+ ImageDir=/run/current-system/sw/share/plymouth/themes/omni-${themeName}
+ ScriptFile=/run/current-system/sw/share/plymouth/themes/omni-${themeName}/omni-${themeName}.script
+ '';
+ };
+
+in
+
+# Create derivation for all Plymouth themes
+stdenv.mkDerivation rec {
+ pname = "omni-plymouth-themes";
+ version = "1.0";
+
+ src = assets;
+
+ buildInputs = with pkgs; [ coreutils ];
+
+ installPhase = ''
+ mkdir -p $out/share/plymouth/themes
+
+ ${lib.concatStringsSep "\n" (
+ lib.mapAttrsToList (themeName: colors: ''
+ # Create theme directory
+ theme_dir="$out/share/plymouth/themes/omni-${themeName}"
+ mkdir -p "$theme_dir"
+
+ # Copy assets
+ cp ${src}/* "$theme_dir/"
+
+ # Install theme files
+ cp ${createPlymouthScript themeName colors} "$theme_dir/omni-${themeName}.script"
+ cp ${createPlymouthTheme themeName colors} "$theme_dir/omni-${themeName}.plymouth"
+
+ # Make script executable
+ chmod +x "$theme_dir/omni-${themeName}.script"
+ '') themeColors
+ )}
+
+ # Create a default symlink to tokyo-night
+ ln -sf omni-tokyo-night $out/share/plymouth/themes/omni-default
+ '';
+
+ meta = with lib; {
+ description = "Omnixient Plymouth boot splash themes";
+ homepage = "https://github.com/TheArctesian/omnixy";
+ license = licenses.mit;
+ platforms = platforms.linux;
+ maintainers = [ ];
+ };
+}
diff --git a/packages/scripts.nix b/packages/scripts.nix
new file mode 100644
index 0000000..5e2d39f
--- /dev/null
+++ b/packages/scripts.nix
@@ -0,0 +1,549 @@
+{ pkgs, lib, ... }:
+
+# Omnixient utility scripts as a Nix package
+pkgs.stdenv.mkDerivation rec {
+ pname = "omni-scripts";
+ version = "1.0.0";
+
+ # No source needed for script-only package
+ dontUnpack = true;
+
+ buildInputs = with pkgs; [
+ bash
+ coreutils
+ gnugrep
+ gnused
+ gawk
+ jq
+ curl
+ wget
+ git
+ fzf
+ ripgrep
+ ];
+
+ installPhase = ''
+ mkdir -p $out/bin
+
+ # Theme management
+ cat > $out/bin/omni-theme-set << 'EOF'
+ #!/usr/bin/env bash
+ set -e
+
+ THEME="$1"
+ AVAILABLE_THEMES="tokyo-night catppuccin gruvbox nord everforest rose-pine kanagawa catppuccin-latte matte-black osaka-jade ristretto"
+
+ if [ -z "$THEME" ]; then
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ exit 1
+ fi
+ echo "Usage: omni theme set " >&2
+ echo "Available themes: $AVAILABLE_THEMES" >&2
+ exit 1
+ fi
+
+ if ! echo "$AVAILABLE_THEMES" | grep -qw "$THEME"; then
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ exit 1
+ fi
+ echo "Error: Unknown theme '$THEME'" >&2
+ echo "Available themes: $AVAILABLE_THEMES" >&2
+ exit 1
+ fi
+
+ # Update configuration
+ sudo sed -i "s/currentTheme = \".*\"/currentTheme = \"$THEME\"/" /etc/nixos/configuration.nix
+
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo "Switching to theme: $THEME"
+ fi
+
+ # Rebuild system
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ sudo nixos-rebuild switch --flake /etc/nixos#omni >/dev/null 2>&1
+ else
+ sudo nixos-rebuild switch --flake /etc/nixos#omni
+ echo "Theme switched to $THEME successfully!"
+ fi
+ EOF
+ chmod +x $out/bin/omni-theme-set
+
+ cat > $out/bin/omni-theme-list << 'EOF'
+ #!/usr/bin/env bash
+
+ THEMES="tokyo-night catppuccin gruvbox nord everforest rose-pine kanagawa catppuccin-latte matte-black osaka-jade ristretto"
+
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ echo "$THEMES" | tr ' ' '\n'
+ exit 0
+ fi
+
+ if [[ "''${OMNI_JSON:-}" == "1" ]]; then
+ current=$(grep currentTheme /etc/nixos/configuration.nix 2>/dev/null | cut -d'"' -f2 || echo "tokyo-night")
+ echo '{'
+ echo ' "available": ["'$(echo "$THEMES" | sed 's/ /", "/g')'"],'
+ echo ' "current": "'$current'"'
+ echo '}'
+ exit 0
+ fi
+
+ echo "Available Omnixient themes:"
+ echo "========================"
+ echo " • tokyo-night (default)"
+ echo " • catppuccin"
+ echo " • gruvbox"
+ echo " • nord"
+ echo " • everforest"
+ echo " • rose-pine"
+ echo " • kanagawa"
+ echo " • catppuccin-latte"
+ echo " • matte-black"
+ echo " • osaka-jade"
+ echo " • ristretto"
+ echo ""
+ echo "Current theme: $(grep currentTheme /etc/nixos/configuration.nix 2>/dev/null | cut -d'"' -f2 || echo "tokyo-night")"
+ echo ""
+ echo "To change theme, run: omni theme set "
+ EOF
+ chmod +x $out/bin/omni-theme-list
+
+ # Get current theme command
+ cat > $out/bin/omni-theme-get << 'EOF'
+ #!/usr/bin/env bash
+ current=$(grep currentTheme /etc/nixos/configuration.nix 2>/dev/null | cut -d'"' -f2 || echo "tokyo-night")
+
+ if [[ "''${OMNI_JSON:-}" == "1" ]]; then
+ echo '{"current": "'$current'"}'
+ else
+ echo "$current"
+ fi
+ EOF
+ chmod +x $out/bin/omni-theme-get
+
+ # System management
+ cat > $out/bin/omni-update << 'EOF'
+ #!/usr/bin/env bash
+ set -e
+
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo "🔄 Updating Omnixient system..."
+ echo ""
+ fi
+
+ # Update flake inputs
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo "📦 Updating flake inputs..."
+ fi
+ cd /etc/nixos
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ sudo nix flake update >/dev/null 2>&1
+ else
+ sudo nix flake update
+ fi
+
+ # Show what changed
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo ""
+ echo "📊 Changes:"
+ git diff flake.lock | grep -E "^\+" | head -20
+ fi
+
+ # Rebuild system
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo ""
+ echo "🏗️ Rebuilding system..."
+ fi
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ sudo nixos-rebuild switch --flake .#omni >/dev/null 2>&1
+ else
+ sudo nixos-rebuild switch --flake .#omni
+ echo ""
+ echo "✅ System updated successfully!"
+ fi
+ EOF
+ chmod +x $out/bin/omni-update
+
+ cat > $out/bin/omni-clean << 'EOF'
+ #!/usr/bin/env bash
+ set -e
+
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo "🧹 Cleaning Omnixient system..."
+ echo ""
+
+ # Show current store size
+ echo "Current store size:"
+ du -sh /nix/store 2>/dev/null || echo "Unable to calculate"
+ echo ""
+ fi
+
+ # Run garbage collection
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo "Running garbage collection..."
+ fi
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ sudo nix-collect-garbage -d >/dev/null 2>&1
+ else
+ sudo nix-collect-garbage -d
+ fi
+
+ # Optimize store
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ echo "Optimizing Nix store..."
+ fi
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ sudo nix-store --optimise >/dev/null 2>&1
+ else
+ sudo nix-store --optimise
+ fi
+
+ if [[ "''${OMNI_QUIET:-}" != "1" ]]; then
+ # Show new size
+ echo ""
+ echo "New store size:"
+ du -sh /nix/store 2>/dev/null || echo "Unable to calculate"
+ echo ""
+ echo "✅ Cleanup complete!"
+ fi
+ EOF
+ chmod +x $out/bin/omni-clean
+
+ # Package management
+ cat > $out/bin/omni-search << 'EOF'
+ #!/usr/bin/env bash
+
+ QUERY="$1"
+
+ if [ -z "$QUERY" ]; then
+ echo "Usage: omni-search "
+ exit 1
+ fi
+
+ echo "Searching for '$QUERY'..."
+ nix search nixpkgs "$QUERY" 2>/dev/null | head -50
+ EOF
+ chmod +x $out/bin/omni-search
+
+ cat > $out/bin/omni-install << 'EOF'
+ #!/usr/bin/env bash
+ set -e
+
+ PACKAGES="$*"
+
+ if [ -z "$PACKAGES" ]; then
+ echo "Usage: omni-install [package-name...]"
+ exit 1
+ fi
+
+ echo "📦 Installing packages: $PACKAGES"
+ echo ""
+
+ # Add packages to configuration
+ CONFIG="/etc/nixos/configuration.nix"
+
+ for PKG in $PACKAGES; do
+ echo "Adding $PKG to configuration..."
+ # This would need more sophisticated editing
+ echo "Package $PKG needs to be manually added to $CONFIG"
+ done
+
+ echo ""
+ echo "Please edit $CONFIG and add the packages to environment.systemPackages"
+ echo "Then run: omni-rebuild"
+ EOF
+ chmod +x $out/bin/omni-install
+
+ # Development helpers
+ cat > $out/bin/omni-dev-shell << 'EOF'
+ #!/usr/bin/env bash
+
+ LANG="$1"
+
+ case "$LANG" in
+ rust)
+ echo "Starting Rust development shell..."
+ nix-shell -p rustc cargo rust-analyzer rustfmt clippy
+ ;;
+ go)
+ echo "Starting Go development shell..."
+ nix-shell -p go gopls gotools golangci-lint
+ ;;
+ python)
+ echo "Starting Python development shell..."
+ nix-shell -p python3 python3Packages.pip python3Packages.virtualenv python3Packages.ipython
+ ;;
+ node|js)
+ echo "Starting Node.js development shell..."
+ nix-shell -p nodejs pnpm typescript
+ ;;
+ c|cpp)
+ echo "Starting C/C++ development shell..."
+ nix-shell -p gcc cmake gnumake gdb clang-tools
+ ;;
+ *)
+ echo "Usage: omni-dev-shell "
+ echo "Supported languages: rust, go, python, node/js, c/cpp"
+ exit 1
+ ;;
+ esac
+ EOF
+ chmod +x $out/bin/omni-dev-shell
+
+ # Screenshot utility
+ cat > $out/bin/omni-screenshot << 'EOF'
+ #!/usr/bin/env bash
+
+ MODE="''${1:-region}"
+ OUTPUT_DIR="$HOME/Pictures/Screenshots"
+ mkdir -p "$OUTPUT_DIR"
+ FILENAME="$OUTPUT_DIR/screenshot-$(date +%Y%m%d-%H%M%S).png"
+
+ case "$MODE" in
+ region|area)
+ grim -g "$(slurp)" "$FILENAME"
+ ;;
+ full|screen)
+ grim "$FILENAME"
+ ;;
+ window)
+ grim -g "$(hyprctl activewindow -j | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')" "$FILENAME"
+ ;;
+ *)
+ echo "Usage: omni-screenshot [region|full|window]"
+ exit 1
+ ;;
+ esac
+
+ if [ -f "$FILENAME" ]; then
+ wl-copy < "$FILENAME"
+ notify-send "Screenshot saved" "$FILENAME" -i "$FILENAME"
+ echo "$FILENAME"
+ fi
+ EOF
+ chmod +x $out/bin/omni-screenshot
+
+ # System info
+ cat > $out/bin/omni-info << 'EOF'
+ #!/usr/bin/env bash
+
+ # Gather data once
+ VERSION=$(nixos-version)
+ KERNEL=$(uname -r)
+ THEME=$(grep currentTheme /etc/nixos/configuration.nix 2>/dev/null | cut -d'"' -f2 || echo "tokyo-night")
+ CPU=$(lscpu | grep 'Model name' | cut -d':' -f2 | xargs)
+ MEMORY=$(free -h | awk '/^Mem:/ {print $2}')
+ DISK=$(df -h / | awk 'NR==2 {print $2}')
+
+ if [[ "''${OMNI_JSON:-}" == "1" ]]; then
+ echo "{"
+ echo " \"system\": {"
+ echo " \"version\": \"$VERSION\","
+ echo " \"kernel\": \"$KERNEL\","
+ echo " \"theme\": \"$THEME\","
+ echo " \"user\": \"$USER\","
+ echo " \"shell\": \"$SHELL\","
+ echo " \"terminal\": \"$TERM\""
+ echo " },"
+ echo " \"hardware\": {"
+ echo " \"cpu\": \"$CPU\","
+ echo " \"memory\": \"$MEMORY\","
+ echo " \"disk\": \"$DISK\""
+ echo " }"
+ echo "}"
+ exit 0
+ fi
+
+ if [[ "''${OMNI_QUIET:-}" == "1" ]]; then
+ echo "version=$VERSION"
+ echo "kernel=$KERNEL"
+ echo "theme=$THEME"
+ echo "user=$USER"
+ echo "shell=$SHELL"
+ echo "terminal=$TERM"
+ echo "cpu=$CPU"
+ echo "memory=$MEMORY"
+ echo "disk=$DISK"
+ exit 0
+ fi
+
+ echo "╭──────────────────────────────╮"
+ echo "│ OMNI NIXOS │"
+ echo "╰──────────────────────────────╯"
+ echo ""
+ echo "System Information:"
+ echo "==================="
+ echo "Version: $VERSION"
+ echo "Kernel: $KERNEL"
+ echo "Theme: $THEME"
+ echo "User: $USER"
+ echo "Shell: $SHELL"
+ echo "Terminal: $TERM"
+ echo ""
+ echo "Hardware:"
+ echo "========="
+ echo "CPU: $CPU"
+ echo "Memory: $MEMORY"
+ echo "Disk: $DISK"
+ echo ""
+ echo "Quick Commands:"
+ echo "=============="
+ echo " omni help - Show help"
+ echo " omni update - Update system"
+ echo " omni clean - Clean system"
+ echo " omni theme - List themes"
+ EOF
+ chmod +x $out/bin/omni-info
+
+ # Help command
+ cat > $out/bin/omni-help << 'EOF'
+ #!/usr/bin/env bash
+
+ cat << HELP
+ Omnixient NixOS - Command Reference
+ ================================
+
+ System Management:
+ ------------------
+ omni-update Update system and flake inputs
+ omni-clean Clean and optimize Nix store
+ omni-rebuild Rebuild system configuration
+ omni-info Show system information
+
+ Package Management:
+ -------------------
+ omni-search Search for packages
+ omni-install Install packages (guide)
+
+ Theme Management:
+ -----------------
+ omni-theme-list List available themes
+ omni-theme-set Set system theme
+
+ Development:
+ ------------
+ omni-dev-shell Start language-specific shell
+ dev-postgres Start PostgreSQL container
+ dev-redis Start Redis container
+ dev-mysql Start MySQL container
+ dev-mongodb Start MongoDB container
+
+ Utilities:
+ ----------
+ omni-screenshot Take screenshots
+
+ Hyprland Keybindings:
+ ---------------------
+ Super + Return Open terminal
+ Super + B Open browser
+ Super + E Open file manager
+ Super + D Application launcher
+ Super + Q Close window
+ Super + F Fullscreen
+ Super + Space Toggle floating
+ Super + 1-9 Switch workspace
+ Super + Shift + 1-9 Move to workspace
+ Print Screenshot region
+ Shift + Print Screenshot full
+
+ For more information: https://github.com/TheArctesian/omnixy
+ HELP
+ EOF
+ chmod +x $out/bin/omni-help
+
+ # Main omni command
+ cat > $out/bin/omni << 'EOF'
+ #!/usr/bin/env bash
+
+ # Parse global flags
+ QUIET=false
+ JSON=false
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ --quiet|-q)
+ QUIET=true
+ export OMNI_QUIET=1
+ shift
+ ;;
+ --json)
+ JSON=true
+ export OMNI_JSON=1
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+
+ CMD="''${1:-help}"
+ shift || true
+
+ case "$CMD" in
+ update|upgrade)
+ omni-update "$@"
+ ;;
+ clean|gc)
+ omni-clean "$@"
+ ;;
+ theme)
+ case "''${1:-}" in
+ set)
+ shift
+ omni-theme-set "$@"
+ ;;
+ list|ls)
+ omni-theme-list "$@"
+ ;;
+ get|current)
+ omni-theme-get "$@"
+ ;;
+ "")
+ omni-theme-list "$@"
+ ;;
+ *)
+ # Legacy: assume it's a theme name
+ omni-theme-set "$@"
+ ;;
+ esac
+ ;;
+ search)
+ omni-search "$@"
+ ;;
+ install)
+ omni-install "$@"
+ ;;
+ info|status)
+ omni-info "$@"
+ ;;
+ help|--help|-h)
+ omni-help "$@"
+ ;;
+ *)
+ if [[ "$QUIET" == "false" ]]; then
+ echo "Unknown command: $CMD" >&2
+ echo "Run 'omni help' for available commands" >&2
+ fi
+ exit 1
+ ;;
+ esac
+ EOF
+ chmod +x $out/bin/omni
+
+ # Create rebuild alias
+ # nh wraps nixos-rebuild with tree-style build output, package diffs, and
+ # profile-aware GC. It handles privilege escalation itself, so no `sudo`
+ # prefix. --hostname pins the nixosConfiguration to "omni" regardless of
+ # the live machine hostname.
+ cat > $out/bin/omni-rebuild << 'EOF'
+ #!/usr/bin/env bash
+ nh os switch --hostname omni /etc/nixos "$@"
+ EOF
+ chmod +x $out/bin/omni-rebuild
+ '';
+
+ meta = with lib; {
+ description = "Omnixient utility scripts for NixOS";
+ license = licenses.mit;
+ platforms = platforms.linux;
+ };
+}
diff --git a/packages/try-cli.nix b/packages/try-cli.nix
new file mode 100644
index 0000000..028011f
--- /dev/null
+++ b/packages/try-cli.nix
@@ -0,0 +1,42 @@
+# packages/try-cli.nix
+#
+# tobi/try — fuzzy-search experiment directory manager.
+# A single-file Ruby script installed via rubygems upstream;
+# we fetch the source directly and wrap it with ruby on PATH.
+{
+ lib,
+ stdenv,
+ fetchFromGitHub,
+ ruby,
+ makeWrapper,
+}:
+
+stdenv.mkDerivation rec {
+ pname = "try-cli";
+ version = "unstable-2026-04-15";
+
+ src = fetchFromGitHub {
+ owner = "tobi";
+ repo = "try";
+ rev = "08ca3e7abc5e0015c9af38d9a2ff65d4fc3c3950";
+ hash = "sha256-yDPQAI/3M1AFsNxBklM5lq8uQwHPr6ryZJBgC2aXGfQ=";
+ };
+
+ nativeBuildInputs = [ makeWrapper ];
+ buildInputs = [ ruby ];
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp try.rb $out/bin/try
+ cp -r lib $out/bin/lib
+ chmod +x $out/bin/try
+ wrapProgram $out/bin/try --prefix PATH : ${ruby}/bin
+ '';
+
+ meta = with lib; {
+ description = "Fresh directories for every vibe — fuzzy experiment manager";
+ homepage = "https://github.com/tobi/try";
+ license = licenses.mit;
+ mainProgram = "try";
+ };
+}