using System; using System.Diagnostics; using System.Linq; using NixWslWrapper.Core.Domain; using NixWslWrapper.Core.Interfaces; using Spectre.Console; namespace NixWslWrapper.Cli { public class CliController { private readonly ICommandExecutor _commandExecutor; public CliController(ICommandExecutor commandExecutor) { _commandExecutor = commandExecutor ?? throw new ArgumentNullException(nameof(commandExecutor)); } public int Run(string[] args) { // Intercept special configuration/status options if (args.Contains("--wsl-status", StringComparer.OrdinalIgnoreCase)) { RenderStatusDashboard(); return 0; } if (args.Contains("--wsl-help", StringComparer.OrdinalIgnoreCase)) { RenderHelp(); return 0; } // Get configuration from environment variables or use defaults string distro = Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") ?? "Debian"; string user = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root"; string profile = Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") ?? "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"; try { PrerequisiteManager.EnsurePrerequisites(distro, user, profile); } catch (Exception ex) { AnsiConsole.MarkupLine($"[bold red]Prerequisite Check Failed:[/] {ex.Message}"); return 1; } WslTarget target; try { target = new WslTarget(distro, user, profile); } catch (Exception ex) { AnsiConsole.MarkupLine($"[red]Configuration Error:[/] {ex.Message}"); return 1; } var nixArgs = new NixArguments(args); var result = _commandExecutor.Execute(nixArgs, target); if (!result.IsSuccess) { if (result.ErrorMessage != null) { AnsiConsole.MarkupLine($"[bold red]Execution Error:[/] {result.ErrorMessage}"); } return result.ExitCode; } return result.ExitCode; } private static void RenderStatusDashboard() { AnsiConsole.Write( new FigletText("Nix WSL Wrapper") .Color(Color.DeepSkyBlue1)); var panel = new Panel( new Markup( "[bold]Nix WSL Wrapper Diagnostic Dashboard[/]\n" + "Wraps native Windows MCP / CLI tool inputs and redirects them into Nix running inside WSL.\n\n" + $"[grey]Generated at: {DateTime.Now:yyyy-MM-dd HH:mm:ss}[/]" )) { Border = BoxBorder.Rounded, Padding = new Padding(1, 1, 1, 1), Header = new PanelHeader("System Info") }; AnsiConsole.Write(panel); // Fetch Environment details string distro = Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") ?? "Debian (Default)"; string user = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root (Default)"; string profile = Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") ?? "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh (Default)"; var table = new Table() .Border(TableBorder.Rounded) .BorderColor(Color.Grey) .AddColumn("[bold]Setting[/]") .AddColumn("[bold]Value[/]") .AddColumn("[bold]Source[/]"); table.AddRow("WSL Target Distro", distro, Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") != null ? "[green]Env Var[/]" : "[yellow]Fallback[/]"); table.AddRow("WSL Execution User", user, Environment.GetEnvironmentVariable("NIX_WSL_USER") != null ? "[green]Env Var[/]" : "[yellow]Fallback[/]"); table.AddRow("Nix Profile Path", profile, Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") != null ? "[green]Env Var[/]" : "[yellow]Fallback[/]"); AnsiConsole.Write(new Rule("[yellow]Configured Parameters[/]") { Justification = Justify.Left }); AnsiConsole.Write(table); // Run WSL check AnsiConsole.Write(new Rule("[yellow]WSL Integration Status[/]") { Justification = Justify.Left }); AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .Start("Verifying WSL and Nix installation...", ctx => { bool wslOk = false; string wslVersion = "Unknown"; try { var psi = new ProcessStartInfo("wsl.exe", "--status") { RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using var p = Process.Start(psi); p?.WaitForExit(3000); wslOk = p?.ExitCode == 0; wslVersion = wslOk ? "WSL Active" : "WSL Error"; } catch { wslVersion = "wsl.exe not found in PATH"; } ctx.Status("Checking Nix inside WSL Distro..."); bool nixOk = false; string nixVersion = "Not Found"; if (wslOk) { try { string targetDistro = Environment.GetEnvironmentVariable("NIX_WSL_DISTRO") ?? "Debian"; string targetUser = Environment.GetEnvironmentVariable("NIX_WSL_USER") ?? "root"; string targetProfile = Environment.GetEnvironmentVariable("NIX_WSL_PROFILE") ?? "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"; var psi = new ProcessStartInfo("wsl.exe", $"-d {targetDistro} -u {targetUser} -- sh -c \". {targetProfile} && nix --version\"") { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using var p = Process.Start(psi); p?.WaitForExit(5000); if (p?.ExitCode == 0) { nixOk = true; nixVersion = p.StandardOutput.ReadToEnd().Trim(); } else { nixVersion = "Nix execution failed inside WSL"; } } catch (Exception ex) { nixVersion = $"Error querying: {ex.Message}"; } } // Render Checks var grid = new Grid().AddColumn().AddColumn(); grid.AddRow(new Markup("wsl.exe Executable Status:"), wslOk ? new Markup("[green]✔ OK[/]") : new Markup($"[red]✘ FAILED ({wslVersion})[/]")); grid.AddRow(new Markup("Nix Engine in WSL Distro:"), nixOk ? new Markup($"[green]✔ OK ({nixVersion})[/]") : new Markup($"[red]✘ FAILED ({nixVersion})[/]")); AnsiConsole.Write(new Panel(grid) { Border = BoxBorder.None }); }); } private static void RenderHelp() { AnsiConsole.Write( new FigletText("Nix WSL Wrapper") .Color(Color.DeepSkyBlue1)); AnsiConsole.MarkupLine("[bold]Usage:[/] nix.exe [[nix-arguments-to-forward]]"); AnsiConsole.MarkupLine("[bold]Alternative flags (Wrapper specific):[/]"); AnsiConsole.MarkupLine(" [yellow]--wsl-status[/] Displays diagnostic status of WSL and Nix integration."); AnsiConsole.MarkupLine(" [yellow]--wsl-help[/] Displays this help menu."); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine("[bold]Configuration Environment Variables:[/]"); AnsiConsole.MarkupLine(" [green]NIX_WSL_DISTRO[/] The target WSL distribution name (default: [grey]Debian[/])."); AnsiConsole.MarkupLine(" [green]NIX_WSL_USER[/] The user to execute commands under (default: [grey]root[/])."); AnsiConsole.MarkupLine(" [green]NIX_WSL_PROFILE[/] The path to the nix-daemon profile script (default: [grey]/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh[/])."); } } }