### Install PoshBuddy from Source Source: https://github.com/julesklord/poshbuddy/blob/main/docs/index.html Clone the repository and install the package locally using Cargo. ```bash git clone https://github.com/julesklord/poshbuddy.git cd poshbuddy cargo install --path . ``` -------------------------------- ### Run PoshBuddy Source: https://github.com/julesklord/poshbuddy/blob/main/docs/index.html Execute the PoshBuddy engine after installation. ```bash poshbuddy ``` -------------------------------- ### Install All Fonts Source: https://context7.com/julesklord/poshbuddy/llms.txt Sequentially installs all available Nerd Fonts, reporting progress for each font. Uses `AppMessage` for progress and completion status. ```rust // Trigger mass font installation app.install_all_fonts(tx.clone()); // Track progress loop { match rx.recv().await { Some(AppMessage::MassFontProgress { index, total, name }) => { println!("[{}/{}] Installing: {}", index, total, name); } Some(AppMessage::Success(msg)) => { println!("{}", msg); break; } Some(AppMessage::Error(e)) => { println!("Error: {}", e); break; } _ => {} } } ``` -------------------------------- ### Install PoshBuddy via Cargo Source: https://github.com/julesklord/poshbuddy/blob/main/docs/index.html Install the PoshBuddy binary using the Rust package manager. ```bash cargo install poshbuddy ``` -------------------------------- ### Manual Winget Installation Source: https://github.com/julesklord/poshbuddy/wiki/troubleshooting Run the installation command manually to diagnose specific Winget error codes. ```powershell winget install JanDeDobbeleer.OhMyPosh ``` -------------------------------- ### Build PoshBuddy from Source Source: https://github.com/julesklord/poshbuddy/blob/main/docs/wiki/index.md Clone the repository, navigate to the directory, and run the cargo command to build the release version. Ensure Rust is installed. ```powershell PS> git clone https://github.com/julesklord/poshbuddy.git PS> cd poshbuddy PS> cargo run --release ``` -------------------------------- ### Manual Oh My Posh Installation Source: https://github.com/julesklord/poshbuddy/wiki/installation Commands to install and verify Oh My Posh if the automatic process fails. ```powershell # Install Oh My Posh PS> winget install JanDeDobbeleer.OhMyPosh # Verify installation PS> oh-my-posh --version 29.9.2 ``` -------------------------------- ### Initialize PoshBuddy Application Source: https://context7.com/julesklord/poshbuddy/llms.txt Initializes the PoshBuddy application, performing system detection, loading themes, and preparing the backup manager. It checks for Oh My Posh installation and gathers system specifications. ```rust use poshbuddy::app::App; // Initialize the application with full system detection let app = App::new(); // The app automatically: // - Detects home directory and creates ~/.poshthemes if needed // - Loads existing local themes from the themes directory // - Detects PowerShell profiles (both PS5.1 and PS7) // - Checks for Nerd Font availability // - Verifies Oh My Posh binary is installed // - Initializes the backup manager // Access detected profiles println!("Detected profiles: {:?}", app.detected_profiles); // Check system specifications if let Some(specs) = &app.system_specs { println!("PowerShell 7: {}", specs.is_pwsh_7); println!("Nerd Font: {}", specs.has_nerd_font); println!("Windows Terminal: {}", specs.is_windows_terminal); } // Check if Oh My Posh is available if app.check_omp_installed() { println!("Oh My Posh is ready!"); } ``` -------------------------------- ### System Diagnostic Output Source: https://github.com/julesklord/poshbuddy/wiki/installation Example output displayed by PoshBuddy during the initial system check. ```text πŸ” SYSTEM DIAGNOSTICS [ √ ] Nerd Font Detected [ √ ] PowerShell 7 Detected [ ! ] Classic Console (Windows Terminal recommended) ``` -------------------------------- ### Install Individual Font Source: https://context7.com/julesklord/poshbuddy/llms.txt Triggers an asynchronous Nerd Font installation using the Oh My Posh CLI. Requires `AppMessage` enum for handling responses. ```rust // Install a specific Nerd Font app.install_font("FiraCode".to_string(), tx.clone()); // Wait for completion match rx.recv().await { Some(AppMessage::FontInstalled(name)) => { println!("Successfully installed: {} Nerd Font", name); } Some(AppMessage::Error(e)) => { println!("Installation failed: {}", e); } _ => {} } ``` -------------------------------- ### Run Full System Diagnostic Source: https://context7.com/julesklord/poshbuddy/llms.txt Performs a comprehensive system check including PowerShell availability, Oh My Posh installation, and profile validation. ```rust let profiles = app.detected_profiles.clone(); let result = diagnostic.run_full_diagnostic(&profiles)?; // Generate a formatted report let report = diagnostic.format_report(&result); println!("{}", report); // Output: // ═══════════════════════════════════════════ // DIAGNOSTIC REPORT // ═══════════════════════════════════════════ // // βœ… Status: ALL GOOD // // πŸ’‘ SUGGESTIONS: // β€’ Profile has UTF-8 BOM. This is normal on Windows. // // ═══════════════════════════════════════════ ``` -------------------------------- ### Integrate Nerd Font Detection in Start-PoshBuddy Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-nerd-font-validator.md Initializes the font check variable at the start of the PoshBuddy execution loop. ```powershell function Start-PoshBuddy { $allThemes = Get-Themes; $index = 0; $filter = ""; $isRunning = $true $hasNerdFont = Test-NerdFont # ADD THIS LINE $lastWin = $Host.UI.RawUI.WindowSize; [Console]::Clear() # ... ``` -------------------------------- ### Font Management API Source: https://context7.com/julesklord/poshbuddy/llms.txt APIs for managing Nerd Fonts, including installing individual fonts and all available fonts. ```APIDOC ## Font Management API ### Installing Individual Fonts #### Description Triggers an asynchronous Nerd Font installation using the Oh My Posh CLI's built-in font installer. #### Method `install_font(font_name: String, tx: Sender)` #### Parameters - `font_name` (String) - Required - The name of the Nerd Font to install. - `tx` (Sender) - Required - A channel sender to receive installation status. #### Response - `AppMessage::FontInstalled(name)` - Indicates successful installation of the specified font. - `AppMessage::Error(e)` - Indicates that the font installation failed. #### Request Example ```rust app.install_font("FiraCode".to_string(), tx.clone()); ``` ### Installing All Fonts #### Description Sequentially installs all available Nerd Fonts with progress reporting for each font. #### Method `install_all_fonts(tx: Sender)` #### Parameters - `tx` (Sender) - Required - A channel sender to receive progress and completion status. #### Response - `AppMessage::MassFontProgress { index, total, name }` - Reports the progress of the mass installation. - `AppMessage::Success(msg)` - Indicates that all fonts have been successfully installed. - `AppMessage::Error(e)` - Indicates that an error occurred during the mass installation. #### Request Example ```rust app.install_all_fonts(tx.clone()); ``` ``` -------------------------------- ### Configure VS Code Font Family Source: https://github.com/julesklord/poshbuddy/blob/main/docs/wiki/troubleshooting.md Set the integrated terminal font family in VS Code settings to a Nerd Font. Ensure the font name matches your installed Nerd Font, such as 'MesloLGS NF'. ```json "terminal.integrated.fontFamily": "'MesloLGS NF'" ``` -------------------------------- ### Basic Main Entry Point Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Initializes the main.rs file with a simple print statement. ```rust fn main() { println!("PoshBuddy Rust v0.2.0-rust"); } ``` -------------------------------- ### Application Initialization Source: https://context7.com/julesklord/poshbuddy/llms.txt Initializes the PoshBuddy application, performing system checks and loading configurations. ```APIDOC ## Application Initialization ### Description The `App::new()` function initializes the PoshBuddy application state, detecting system capabilities, loading local themes, and preparing the backup manager. It automatically checks for Oh My Posh installation and gathers system specifications. ### Method `App::new()` ### Endpoint N/A (Local application initialization) ### Parameters None ### Request Example ```rust use poshbuddy::app::App; // Initialize the application with full system detection let app = App::new(); ``` ### Response #### Success Response (Initialization) - **app** (App) - The initialized PoshBuddy application instance. #### Response Example ```rust // Access detected profiles println!("Detected profiles: {:?}", app.detected_profiles); // Check system specifications if let Some(specs) = &app.system_specs { println!("PowerShell 7: {}", specs.is_pwsh_7); println!("Nerd Font: {}", specs.has_nerd_font); println!("Windows Terminal: {}", specs.is_windows_terminal); } // Check if Oh My Posh is available if app.check_omp_installed() { println!("Oh My Posh is ready!"); } ``` ``` -------------------------------- ### Git Initialization Commands Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Stages and commits the initial project files. ```bash git add Cargo.toml src/main.rs git commit -m "chore: initialize cargo project" ``` -------------------------------- ### Define Theme and App Structures Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Sets up the core data models and application state management, including path resolution for different operating systems. ```rust use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Serialize, Deserialize, Clone, Debug)] struct Theme { name: String, download_url: String, } struct App { themes: Vec, selected_index: usize, filter: String, should_quit: bool, themes_dir: PathBuf, profile_path: PathBuf, } impl App { fn new() -> Self { let home = dirs::home_dir().expect("Could not find home directory"); let themes_dir = home.join(".poshthemes"); let profile_path = if cfg!(windows) { home.join("Documents/PowerShell/Microsoft.PowerShell_profile.ps1") } else { home.join(".config/powershell/Microsoft.PowerShell_profile.ps1") }; App { themes: Vec::new(), selected_index: 0, filter: String::new(), should_quit: false, themes_dir, profile_path, } } fn filtered_themes(&self) -> Vec<&String> { self.themes .iter() .filter(|t| t.to_lowercase().contains(&self.filter.to_lowercase())) .collect() } } ``` -------------------------------- ### Explore PoshBuddy Themes Source: https://github.com/julesklord/poshbuddy/blob/main/docs/index.html Launch the interactive TUI to browse and apply themes. ```bash poshbuddy --explore ``` -------------------------------- ### Implement Main Event Loop Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Sets up the terminal raw mode and processes keyboard events to control the application state. ```rust use crossterm::{ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use std::io; #[tokio::main] async fn main() -> Result<(), Box> { // Setup terminal enable_raw_mode()?; let mut stdout = io::stdout(); execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; let mut app = App::new(); app.themes = fetch_themes().await.unwrap_or_default(); loop { terminal.draw(|f| ui(f, &mut app))?; if event::poll(std::time::Duration::from_millis(100))? { if let Event::Key(key) = event::read()? { match key.code { KeyCode::Char('q') | KeyCode::Esc => break, KeyCode::Down => { let total = app.filtered_themes().len(); if total > 0 { app.selected_index = (app.selected_index + 1) % total; } } KeyCode::Up => { let total = app.filtered_themes().len(); if total > 0 { app.selected_index = (app.selected_index + total - 1) % total; } } KeyCode::Char(c) => { app.filter.push(c); app.selected_index = 0; } KeyCode::Backspace => { app.filter.pop(); app.selected_index = 0; } _ => {} } } } } // Restore terminal disable_raw_mode()?; execute!( terminal.backend_mut(), LeaveAlternateScreen, DisableMouseCapture )?; terminal.show_cursor()?; Ok(()) } ``` -------------------------------- ### Implement apply_theme function in Rust Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Updates the PowerShell profile file to include the oh-my-posh initialization command. Requires the regex crate for pattern matching existing configuration lines. ```rust use std::fs; impl App { fn apply_theme(&self, theme_name: &str) -> io::Result<()> { let theme_path = self.themes_dir.join(theme_name); let config_line = format!("oh-my-posh init pwsh --config '{}' | Invoke-Expression", theme_path.display()); let content = if self.profile_path.exists() { fs::read_to_string(&self.profile_path)? } else { String::new() }; let mut new_content = Vec::new(); let mut found = false; let re = regex::Regex::new(r"(?i)^oh-my-posh init .*").unwrap(); for line in content.lines() { if re.is_match(line) { new_content.push(config_line.clone()); found = true; } else { new_content.push(line.to_string()); } } if !found { new_content.push(config_line); } fs::write(&self.profile_path, new_content.join("\n"))?; Ok(()) } } ``` -------------------------------- ### Implement Async Theme Fetching Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Fetches theme names from the Oh My Posh GitHub repository using an asynchronous HTTP client. ```rust async fn fetch_themes() -> Result, Box> { let url = "https://api.github.com/repos/JanDeDobbeleer/oh-my-posh/contents/themes"; let client = reqwest::Client::builder() .user_agent("PoshBuddy-Rust") .build()?; let resp = client.get(url).send().await?.json::>().await?; let themes = resp.into_iter() .filter_map(|v| v["name"].as_str().map(|s| s.to_string())) .filter(|s| s.ends_with(".omp.json")) .collect(); Ok(themes) } ``` -------------------------------- ### Generate Theme Preview Source: https://context7.com/julesklord/poshbuddy/llms.txt Generates a real-time preview of a theme. Automatically cancels previous requests to prevent race conditions. Requires `ThemeAsset` and `AppMessage` types. ```rust let theme = ThemeAsset { name: "powerlevel10k_lean".to_string(), is_local: true, download_url: None, }; // Request preview generation (async) app.load_theme_preview(theme.clone(), tx.clone()); // Receive the preview when ready if let Some(AppMessage::ThemePreviewLoaded { theme, preview, request_id }) = rx.recv().await { println!("Preview for '{}' (request #{})\n", theme.name, request_id); println!("{}", preview); // Output: ANSI-formatted prompt preview string } ``` -------------------------------- ### Initialize Cargo Project Dependencies Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Defines the required dependencies for the PoshBuddy Rust project in Cargo.toml. ```toml [package] name = "poshbuddy" version = "0.2.0-rust" edition = "2021" [dependencies] ratatui = "0.26" crossterm = { version = "0.27", features = ["event-stream"] } reqwest = { version = "0.11", features = ["json"] } tokio = { version = "1", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" dirs = "5.0" futures = "0.3" ``` -------------------------------- ### Optimize Oh My Posh Initialization Source: https://github.com/julesklord/poshbuddy/blob/main/docs/wiki/troubleshooting.md Ensure your PowerShell profile is optimized by PoshBuddy with the correct initialization line for `oh-my-posh`. This helps prevent terminal latency and slow startup. ```powershell oh-my-posh init pwsh ... ``` -------------------------------- ### Create Profile Backup Source: https://context7.com/julesklord/poshbuddy/llms.txt Creates an automatic backup of a PowerShell profile before modifications. Limits the number of backups per file. Requires `BackupManager` and `Path`. ```rust use poshbuddy::backup::BackupManager; use std::path::Path; let backup_manager = BackupManager::new(Some(5)); // Keep max 5 backups per file let profile_path = Path::new("C:\\Users\\user\\Documents\\PowerShell\\Microsoft.PowerShell_profile.ps1"); // Create a backup with description match backup_manager.backup_profile(profile_path, "Before applying agnoster theme") { Ok(backup_path) => { println!("Backup created at: {}", backup_path.display()); } Err(e) => { println!("Backup failed: {}", e); } } ``` -------------------------------- ### Download Theme File Source: https://context7.com/julesklord/poshbuddy/llms.txt Downloads a remote theme to a local directory with error handling and timeout protection. ```rust use poshbuddy::api::download_theme_file; let theme_path = download_theme_file( "gruvbox", "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/gruvbox.omp.json", &app.themes_dir, ).await?; println!("Theme saved to: {}", theme_path.display()); ``` -------------------------------- ### Backup Manager API Source: https://context7.com/julesklord/poshbuddy/llms.txt Provides functionality for backing up and listing Oh My Posh profile configurations. ```APIDOC ## Backup Manager API ### Creating Backups #### Description Creates automatic backups of profile modifications with metadata. Backups are limited to prevent excessive accumulation. #### Method `BackupManager::new(max_backups: Option) -> BackupManager` `backup_profile(profile_path: &Path, description: &str) -> Result` #### Parameters - `max_backups` (Option) - Optional - The maximum number of backups to keep per file. - `profile_path` (Path) - Required - The path to the profile file to back up. - `description` (str) - Required - A description for the backup. #### Response - `Ok(backup_path)` - The path to the created backup file on success. - `Err(e)` - An error describing the failure. #### Request Example ```rust use poshbuddy::backup::BackupManager; use std::path::Path; let backup_manager = BackupManager::new(Some(5)); // Keep max 5 backups per file let profile_path = Path::new("C:\\Users\\user\\Documents\\PowerShell\\Microsoft.PowerShell_profile.ps1"); match backup_manager.backup_profile(profile_path, "Before applying agnoster theme") { Ok(backup_path) => { println!("Backup created at: {}", backup_path.display()); } Err(e) => { println!("Backup failed: {}", e); } } ``` ### Listing Backups #### Description Retrieves a list of all available backups for a given profile, ordered from most recent to oldest. #### Method `list_backups(profile_path: &Path) -> Result>` #### Parameters - `profile_path` (Path) - Required - The path to the profile file for which to list backups. #### Response - `Ok(Vec)` - A vector of `BackupInfo` structs, each containing backup timestamp and description. - `Err(e)` - An error describing the failure. #### Response Example ```rust let backups = backup_manager.list_backups(profile_path)?; println!("Found {} backups:", backups.len()); for backup in &backups { let datetime = chrono::NaiveDateTime::from_timestamp_millis(backup.timestamp as i64) .unwrap_or_default(); println!(" - {} | {}", datetime.format("%Y-%m-%d %H:%M"), backup.description); } ``` ``` -------------------------------- ### Commit UI Changes Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Git commands to stage and commit the UI implementation changes. ```bash git add src/main.rs git commit -m "feat: add TUI rendering logic" ``` -------------------------------- ### Apply Oh My Posh Theme Source: https://context7.com/julesklord/poshbuddy/llms.txt Applies a theme using a 4-stage atomic process: Download, Verify, Backup, Apply. Ensures safe profile modification with automatic rollback on failure. Monitors progress via messages. ```rust use poshbuddy::app::{App, AppMessage, ThemeAsset}; let theme = ThemeAsset { name: "agnoster".to_string(), is_local: false, download_url: Some("https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/agnoster.omp.json".to_string()), }; // Apply theme with full transaction pipeline app.apply_theme_advanced(theme, tx.clone()); // Monitor progress through messages while let Some(msg) = rx.recv().await { match msg { AppMessage::InstallUpdate { stage, percentage } => { let stage_name = match stage { 0 => "Downloading", 1 => "Verifying JSON", 2 => "Creating Backup", 3 => "Applying to Profiles", _ => "Unknown", }; println!("[{:.0}%] {}", percentage, stage_name); } AppMessage::Success(message) => { println!("Success: {}", message); break; } AppMessage::Error(error) => { println!("Error: {}", error); break; } _ => {} } } ``` -------------------------------- ### Frontend UI Utilities Source: https://github.com/julesklord/poshbuddy/blob/main/docs/index.html JavaScript utilities for scroll animations and tab switching functionality. ```javascript // Scroll reveal via IntersectionObserver const observer = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); } }); }, { threshold: 0.1 }); document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); // Nav scroll effect window.addEventListener('scroll', () => { document.getElementById('nav').classList.toggle('scrolled', window.scrollY > 50); }, { passive: true }); // Install tabs function switchTab(btn, panelId) { document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active')); btn.classList.add('active'); document.getElementById(panelId).classList.add('active'); } ``` -------------------------------- ### List Profile Backups Source: https://context7.com/julesklord/poshbuddy/llms.txt Retrieves a list of all available backups for a specific profile, ordered from most recent to oldest. Requires `chrono` for timestamp formatting. ```rust let backups = backup_manager.list_backups(profile_path)?; println!("Found {} backups:", backups.len()); for backup in &backups { let datetime = chrono::NaiveDateTime::from_timestamp_millis(backup.timestamp as i64) .unwrap_or_default(); println!(" - {} | {}", datetime.format("%Y-%m-%d %H:%M"), backup.description); } ``` -------------------------------- ### Fetch Remote Oh My Posh Themes Source: https://context7.com/julesklord/poshbuddy/llms.txt Asynchronously fetches the complete theme catalog from the official Oh My Posh GitHub repository using message passing for communication. Handles messages for loaded themes and fonts. ```rust use tokio::sync::mpsc; use poshbuddy::app::{App, AppMessage}; // Create a channel for async communication let (tx, mut rx) = mpsc::channel::(64); // Start fetching themes in the background app.fetch_official_themes(tx.clone()); // Handle incoming messages in your event loop while let Some(msg) = rx.recv().await { match msg { AppMessage::RemoteThemesLoaded(themes) => { println!("Loaded {} remote themes", themes.len()); for theme in themes.iter().take(5) { println!(" - {} ({})", theme.name, theme.download_url); } } AppMessage::FontsLoaded(fonts) => { println!("Loaded {} Nerd Fonts", fonts.len()); } _ => {} } } ``` -------------------------------- ### Toggle PowerShell Plugins with PoshBuddy Source: https://context7.com/julesklord/poshbuddy/llms.txt Uses the toggle_plugin method to enable or disable a plugin. Requires a PluginAsset struct and handles potential errors during the toggle process. ```rust use poshbuddy::app::PluginAsset; let terminal_icons = PluginAsset { name: "Terminal-Icons".to_string(), description: "Adds file and folder icons to terminal outputs.".to_string(), documentation: "Requires a Nerd Font.".to_string(), module_name: "Terminal-Icons".to_string(), init_script: None, }; // Toggle the plugin (backup is created automatically) match app.toggle_plugin(&terminal_icons) { Ok(()) => { let status = if app.is_plugin_active(&terminal_icons) { "activated" } else { "deactivated" }; println!("Terminal-Icons is now {}", status); } Err(e) => { println!("Failed to toggle plugin: {}", e); } } ``` -------------------------------- ### Theme Preview Generation Source: https://context7.com/julesklord/poshbuddy/llms.txt Generates an isolated real-time preview of a theme using the Oh My Posh CLI. It automatically cancels previous preview requests to prevent race conditions. ```APIDOC ## Theme Preview Generation ### Description Generates an isolated real-time preview of a theme using the Oh My Posh CLI. It automatically cancels previous preview requests to prevent race conditions. ### Method `load_theme_preview()` ### Parameters - `theme` (ThemeAsset) - Required - The theme configuration to preview. - `tx` (Sender) - Required - A channel sender to receive the preview result. ### Request Example ```rust let theme = ThemeAsset { name: "powerlevel10k_lean".to_string(), is_local: true, download_url: None, }; app.load_theme_preview(theme.clone(), tx.clone()); ``` ### Response #### Success Response - `AppMessage::ThemePreviewLoaded` - Contains the theme name, the generated preview string, and the request ID. #### Response Example ```rust if let Some(AppMessage::ThemePreviewLoaded { theme, preview, request_id }) = rx.recv().await { println!("Preview for '{}' (request #{})\n{}\n", theme.name, request_id, preview); // Output: ANSI-formatted prompt preview string } ``` ``` -------------------------------- ### Switch to Feature Branch Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-nerd-font-validator.md Creates and switches to a new branch for the Nerd Font validator feature. ```bash git checkout -b feat/nerd-font-validator ``` -------------------------------- ### Render Terminal UI with Ratatui Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Defines the UI layout and rendering logic for a theme selection interface using Ratatui widgets. ```rust use ratatui::{ backend::CrosstermBackend, layout::{Constraint, Direction, Layout}, style::{Color, Modifier, Style}, widgets::{Block, Borders, List, ListItem, ListState, Paragraph}, Terminal, }; fn ui(f: &mut ratatui::Frame, app: &mut App) { let chunks = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(30), Constraint::Percentage(70)].as_ref()) .split(f.size()); let filtered = app.filtered_themes(); let items: Vec = filtered .iter() .enumerate() .map(|(i, t)| { let style = if i == app.selected_index { Style::default().fg(Color::Green).add_modifier(Modifier::BOLD) } else { Style::default().fg(Color::Gray) }; ListItem::new(t.as_str()).style(style) }) .collect(); let themes_list = List::new(items) .block(Block::default().borders(Borders::ALL).title("Themes")) .highlight_symbol("> "); f.render_widget(themes_list, chunks[0]); let preview_text = if !filtered.is_empty() { format!("Previewing: {}\n\nPress Enter to apply.", filtered[app.selected_index]) } else { "No themes found.".to_string() }; let preview = Paragraph::new(preview_text) .block(Block::default().borders(Borders::ALL).title("Preview")); f.render_widget(preview, chunks[1]); } ``` -------------------------------- ### Querying the active PowerShell profile path Source: https://github.com/julesklord/poshbuddy/blob/main/docs/wiki/usage.md This command is used internally by PoshBuddy to identify the current user's profile location, accounting for relocated Documents folders. ```powershell # PoshBuddy executes this internally to find YOUR path PS> Write-Host -NoNewline $PROFILE # Output: D:\Documents\PowerShell\Microsoft.PowerShell_profile.ps1 ``` -------------------------------- ### Check Internet Connectivity Source: https://context7.com/julesklord/poshbuddy/llms.txt Performs a fast network check before attempting downloads. ```rust use poshbuddy::api::check_internet_connectivity; if check_internet_connectivity() { println!("Internet connection available"); app.fetch_official_themes(tx.clone()); } else { println!("No internet - using cached/local themes only"); } ``` -------------------------------- ### Backup Management API Source: https://context7.com/julesklord/poshbuddy/llms.txt API for managing backups, including restoring the latest backup. ```APIDOC ## POST /api/backup/restore_latest ### Description Restores the most recent backup for a profile, automatically creating a pre-restore backup of the current state. ### Method POST ### Endpoint /api/backup/restore_latest ### Parameters #### Path Parameters - **profile_path** (string) - Required - The path to the profile to restore. ### Request Body None ### Response #### Success Response (200) - **restored_backup** (object) - Information about the restored backup. - **path** (string) - The path to the restored backup file. - **description** (string) - The description of the restored backup. #### Error Response (404) - **error** (string) - Indicates that no backups were found for the profile. #### Error Response (500) - **error** (string) - Indicates a general restore failure. ### Request Example None ### Response Example ```json { "restored_backup": { "path": "/path/to/backup/2023-10-27_10-00-00.zip", "description": "Pre-restore backup" } } ``` ``` -------------------------------- ### Display Nerd Font Warning in UI Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-nerd-font-validator.md Renders a warning message in the preview panel if the font check fails. ```powershell # View: Preview Panel if ($total -gt 0) { # ... (existing code) oh-my-posh print primary --config $localPath --shell pwsh | Out-String | Write-Host -NoNewline if (!$hasNerdFont) { $p = $Host.UI.RawUI.CursorPosition; $p.X = $leftW + 4; $p.Y = $panelH - 2 $Host.UI.RawUI.CursorPosition = $p Write-Host "⚠️ Nerd Font no detectada. Los iconos podrΓ­an no verse bien." -ForegroundColor DarkYellow } $p.Y = 7; $Host.UI.RawUI.CursorPosition = $p; Write-Host "METRICAS DE CARGA:" -ForegroundColor DarkGray # ... } ``` -------------------------------- ### Restore Latest Backup Source: https://context7.com/julesklord/poshbuddy/llms.txt Restores the most recent backup for a profile, creating a pre-restore backup of the current state. ```rust // Restore the most recent backup match backup_manager.restore_latest(profile_path) { Ok(restored_backup) => { println!("Restored backup from: {}", restored_backup.path.display()); println!("Description: {}", restored_backup.description); } Err(poshbuddy::backup::BackupError::BackupNotFound(_)) => { println!("No backups available for this profile"); } Err(e) => { println!("Restore failed: {}", e); } } ``` -------------------------------- ### Update Profile Safely Source: https://context7.com/julesklord/poshbuddy/llms.txt Manages PowerShell profile sections using secure markers to ensure changes are localized and reversible. ```rust let profile = Path::new("C:\\Users\\user\\Documents\\PowerShell\\Microsoft.PowerShell_profile.ps1"); // Add or update a managed section app.update_profile_safe( profile, "THEME", // Section key "oh-my-posh init powershell --config \"~/.poshthemes/agnoster.omp.json\" | Invoke-Expression", "Apply Oh My Posh theme: agnoster" )?; // The profile will contain: // ## POSHBUDDY AUTO-GENERATED CONFIG - START (THEME) // ## Description: Apply Oh My Posh theme: agnoster // oh-my-posh init powershell --config "~/.poshthemes/agnoster.omp.json" | Invoke-Expression // ## POSHBUDDY AUTO-GENERATED CONFIG - END (THEME) ``` -------------------------------- ### Configure Git Identity Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-nerd-font-validator.md Sets the local Git user name and email for the repository. ```bash git config user.name "Snuggles" git config user.email "snuggles@poshbuddy.dev" ``` -------------------------------- ### Commit Changes Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-nerd-font-validator.md Stages and commits the implemented changes to the repository. ```bash git add PoshBuddy.ps1 git commit -m "feat: add Nerd Font detection and warning indicator" ``` -------------------------------- ### Commit Event Loop Changes Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Git commands to stage and commit the event loop implementation. ```bash git add src/main.rs git commit -m "feat: implement main event loop" ``` -------------------------------- ### Theme Management API Source: https://context7.com/julesklord/poshbuddy/llms.txt APIs for managing Oh My Posh themes, including fetching remote themes, filtering, and applying them. ```APIDOC ## Theme Management API ### Fetching Remote Themes #### Description The `fetch_official_themes()` method asynchronously fetches the complete theme catalog from the official Oh My Posh GitHub repository. It uses message passing to communicate results back to the main application loop. ### Method `fetch_official_themes(tx: Sender)` ### Endpoint N/A (Internal API call) ### Parameters - **tx** (Sender) - A channel sender to send `AppMessage::RemoteThemesLoaded` upon completion. ### Request Example ```rust use tokio::sync::mpsc; use poshbuddy::app::{App, AppMessage}; // Create a channel for async communication let (tx, mut rx) = mpsc::channel::(64); // Start fetching themes in the background app.fetch_official_themes(tx.clone()); ``` ### Response #### Success Response (Message) - **AppMessage::RemoteThemesLoaded(themes)** - Contains a vector of `ThemeAsset` objects representing the fetched themes. #### Response Example ```rust // Handle incoming messages in your event loop while let Some(msg) = rx.recv().await { match msg { AppMessage::RemoteThemesLoaded(themes) => { println!("Loaded {} remote themes", themes.len()); for theme in themes.iter().take(5) { println!(" - {} ({})", theme.name, theme.download_url); } } AppMessage::FontsLoaded(fonts) => { println!("Loaded {} Nerd Fonts", fonts.len()); } _ => {} } } ``` ``` ```APIDOC ### Filtering Themes #### Description The `filtered_themes()` method returns a unified list of local and remote themes filtered by the current search query. It performs case-insensitive matching and deduplicates entries. ### Method `filtered_themes() -> Vec` ### Endpoint N/A (Local method call) ### Parameters None (operates on the `filter` field of the `App` struct) ### Request Example ```rust // Set a filter query app.filter = "catppuccin".to_string(); // Get filtered results (combines local and remote themes) let themes = app.filtered_themes(); ``` ### Response #### Success Response (200) - **themes** (Vec) - A vector of `ThemeAsset` objects matching the filter. #### Response Example ```rust for theme in &themes { let status = if theme.is_local { "LOCAL" } else { "REMOTE" }; println!("[{}] {}", status, theme.name); } // Output: // [LOCAL] catppuccin_frappe // [REMOTE] catppuccin_latte // [REMOTE] catppuccin_macchiato // [REMOTE] catppuccin_mocha ``` ``` ```APIDOC ### Applying Themes #### Description The `apply_theme_advanced()` method performs a 4-stage atomic theme application: Download -> Verify -> Backup -> Apply. It ensures safe profile modification with automatic rollback on failure. ### Method `apply_theme_advanced(theme: ThemeAsset, tx: Sender)` ### Endpoint N/A (Internal API call) ### Parameters - **theme** (ThemeAsset) - The theme to apply. - **tx** (Sender) - A channel sender to receive progress and status updates. ### Request Example ```rust use poshbuddy::app::{App, AppMessage, ThemeAsset}; let theme = ThemeAsset { name: "agnoster".to_string(), is_local: false, download_url: Some("https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/agnoster.omp.json".to_string()), }; // Apply theme with full transaction pipeline app.apply_theme_advanced(theme, tx.clone()); ``` ### Response #### Success Response (Message) - **AppMessage::Success(message)** - Indicates successful theme application. - **AppMessage::InstallUpdate** - Provides progress updates during the application stages. #### Response Example ```rust // Monitor progress through messages while let Some(msg) = rx.recv().await { match msg { AppMessage::InstallUpdate { stage, percentage } => { let stage_name = match stage { 0 => "Downloading", 1 => "Verifying JSON", 2 => "Creating Backup", 3 => "Applying to Profiles", _ => "Unknown", }; println!("[{:.0}%] {}", percentage, stage_name); } AppMessage::Success(message) => { println!("Success: {}", message); break; } AppMessage::Error(error) => { println!("Error: {}", error); break; } _ => {} } } ``` ``` -------------------------------- ### Commit changes to version control Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Stages and commits the modified source and configuration files to the repository. ```bash git add src/main.rs Cargo.toml git commit -m "feat: add powershell profile integration" ``` -------------------------------- ### Define Test-NerdFont Function Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-nerd-font-validator.md Checks the current host font name for Nerd Font compatibility markers. ```powershell function Test-NerdFont { try { $fontName = "" if ($IsWindows) { $fontName = $Host.UI.RawUI.FontName if (!$fontName) { $fontName = (Get-ItemProperty -Path "HKCU:\Console" -ErrorAction SilentlyContinue).FaceName } } return ($fontName -match "NF|Nerd|Retina") } catch { return $false } } ``` -------------------------------- ### Network API Source: https://context7.com/julesklord/poshbuddy/llms.txt API for network operations, including downloading theme files and checking internet connectivity. ```APIDOC ## POST /api/network/download_theme ### Description Downloads a remote theme file to a local directory with proper error handling and timeout protection. ### Method POST ### Endpoint /api/network/download_theme ### Parameters #### Path Parameters None #### Query Parameters - **theme_name** (string) - Required - The name of the theme to download. - **theme_url** (string) - Required - The URL of the theme file. - **themes_dir** (string) - Required - The local directory where the theme should be saved. ### Request Body None ### Response #### Success Response (200) - **theme_path** (string) - The local path where the theme file was saved. #### Error Response (500) - **error** (string) - Indicates a failure during the theme download process. ### Request Example None ### Response Example ```json { "theme_path": "/path/to/local/themes/gruvbox.omp.json" } ``` ``` ```APIDOC ## GET /api/network/check_connectivity ### Description Performs a fast network check to determine if an internet connection is available. ### Method GET ### Endpoint /api/network/check_connectivity ### Parameters None ### Request Body None ### Response #### Success Response (200) - **is_connected** (boolean) - True if an internet connection is available, false otherwise. #### Response Example ```json { "is_connected": true } ``` ``` -------------------------------- ### Reload PowerShell Profile Source: https://github.com/julesklord/poshbuddy/blob/main/docs/wiki/troubleshooting.md Execute this command to force-reload your PowerShell configuration in the active window. This is useful when themes are not applying after a "Success" notification. ```powershell . $PROFILE ``` -------------------------------- ### Segment Management API Source: https://context7.com/julesklord/poshbuddy/llms.txt APIs for managing segments within the Oh My Posh theme configuration. ```APIDOC ## Segment Management API ### Checking Active Segments #### Description Checks if a specific Oh My Posh segment is currently enabled in the active theme configuration. #### Method `is_segment_active(segment: &SegmentAsset) -> bool` #### Parameters - `segment` (SegmentAsset) - Required - The segment to check for activity. #### Response - `true` if the segment is active, `false` otherwise. #### Request Example ```rust use poshbuddy::app::SegmentAsset; app.refresh_active_segments(); let git_segment = SegmentAsset { name: "Git Status".to_string(), segment_type: "git".to_string(), description: "Shows current branch and Git file status.".to_string(), documentation: "Essential for collaborative development.".to_string(), category: "Development".to_string(), }; if app.is_segment_active(&git_segment) { println!("Git segment is currently enabled in your theme"); } else { println!("Git segment is not active"); } ``` ### Toggling Segments #### Description Adds or removes a segment from the active Oh My Posh theme configuration. #### Method `toggle_segment(segment: &SegmentAsset) -> Result<()> #### Parameters - `segment` (SegmentAsset) - Required - The segment to toggle. #### Response - `Ok(())` on success. - `Err(e)` on failure, where `e` is an error describing the issue. #### Request Example ```rust let battery_segment = SegmentAsset { name: "Battery".to_string(), segment_type: "battery".to_string(), description: "Displays battery percentage and charging status.".to_string(), documentation: "Changes color based on charge level.".to_string(), category: "System".to_string(), }; match app.toggle_segment(&battery_segment) { Ok(()) => { let status = if app.is_segment_active(&battery_segment) { "enabled" } else { "disabled" }; println!("Battery segment is now {}", status); } Err(e) => { println!("Failed to toggle segment: {}", e); } } ``` ``` -------------------------------- ### Toggle Segment Source: https://context7.com/julesklord/poshbuddy/llms.txt Adds or removes a segment from the active Oh My Posh theme configuration. Returns `Ok(())` on success or an error message. ```rust let battery_segment = SegmentAsset { name: "Battery".to_string(), segment_type: "battery".to_string(), description: "Displays battery percentage and charging status.".to_string(), documentation: "Changes color based on charge level.".to_string(), category: "System".to_string(), }; // Toggle the segment (add if missing, remove if present) match app.toggle_segment(&battery_segment) { Ok(()) => { let status = if app.is_segment_active(&battery_segment) { "enabled" } else { "disabled" }; println!("Battery segment is now {}", status); } Err(e) => { println!("Failed to toggle segment: {}", e); } } ``` -------------------------------- ### Validate PowerShell Syntax Source: https://context7.com/julesklord/poshbuddy/llms.txt Provides syntax validation for PowerShell scripts before applying changes. ```rust use poshbuddy::diagnostic::Diagnostic; let diagnostic = Diagnostic::new(); let script = r#" function Test-Example { Write-Host "Hello" oh-my-posh init pwsh --config 'C:\themes\test.omp.json' | Invoke-Expression } "#; let result = diagnostic.validate_powershell_syntax(script)?; if result.is_valid() { println!("Syntax is valid!"); } else { for error in &result.errors { println!("Error: {}", error); } } for warning in &result.warnings { println!("Warning: {}", warning); } for suggestion in &result.suggestions { println!("Suggestion: {}", suggestion); } ``` -------------------------------- ### Commit Data Structure Changes Source: https://github.com/julesklord/poshbuddy/blob/main/docs/superpowers/plans/2026-04-05-rust-port.md Stages and commits the updated source code. ```bash git add src/main.rs git commit -m "feat: add data structures and theme fetching" ``` -------------------------------- ### Filter Oh My Posh Themes Source: https://context7.com/julesklord/poshbuddy/llms.txt Filters a unified list of local and remote themes based on a search query. Performs case-insensitive matching and deduplicates entries. Displays the status (LOCAL/REMOTE) and name of each matching theme. ```rust // Set a filter query app.filter = "catppuccin".to_string(); // Get filtered results (combines local and remote themes) let themes = app.filtered_themes(); for theme in &themes { let status = if theme.is_local { "LOCAL" } else { "REMOTE" }; println!("[{}] {}", status, theme.name); } // Output: // [LOCAL] catppuccin_frappe // [REMOTE] catppuccin_latte // [REMOTE] catppuccin_macchiato // [REMOTE] catppuccin_mocha ```