using Sdt.Config; using Sdt.Tui; using Spectre.Console; // ── Workspace + project discovery ──────────────────────────────────────────── var workspaceResult = WorkspaceLoader.FindAndLoad(); var projectResult = ConfigLoader.FindAndLoad(); if (projectResult is null) { AnsiConsole.MarkupLine($"[bold {Theme.Red}]SDT:[/] [{Theme.Amber}]No devtool.json found[/] in current directory or any parent."); AnsiConsole.MarkupLine(Theme.Faint("Create a devtool.json in your project root to get started.")); return 1; } // ── Main run loop (handles workspace project switching) ─────────────────────── var (currentConfig, currentRoot) = projectResult.Value; var (workspace, workspaceRoot) = workspaceResult.HasValue ? (workspaceResult.Value.Config, workspaceResult.Value.WorkspaceRoot) : ((WorkspaceConfig?)null, (string?)null); try { while (true) { var app = new App(currentConfig, currentRoot, workspace, workspaceRoot); var result = await app.RunAsync(); if (result.Reason == AppExitReason.Quit) break; // User switched projects — reload config from new root if (result.Reason == AppExitReason.SwitchProject && result.NewProjectRoot is not null) { var loaded = ConfigLoader.FindAndLoad(result.NewProjectRoot); if (loaded is null) { AnsiConsole.MarkupLine(Theme.Fail($"No devtool.json found at: {result.NewProjectRoot}")); AnsiConsole.MarkupLine(Theme.Faint("Press any key to stay on current project...")); Console.ReadKey(intercept: true); continue; // go back to current app } (currentConfig, currentRoot) = loaded.Value; } } return 0; } catch (Exception ex) { AnsiConsole.MarkupLine(Theme.Fail($"Fatal: {ex.Message}")); AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything); return 1; }