Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
21af733
feat: integrate Ratatui for TUI dashboard and update dependencies
0xParthP Sep 5, 2026
7712c2e
feat: add TUI module with event handling and UI tests
0xParthP Sep 5, 2026
29a5134
feat: refactor TUI event handling and add tests for run_loop function…
0xParthP Sep 5, 2026
15265d0
refactor: update run_loop and event handling for improved clarity and…
0xParthP Sep 5, 2026
3a02cd9
feat: update TUI event handling and add tests for run_loop and tick f…
0xParthP Sep 5, 2026
eb50520
refactor: remove unused event handling tests and streamline run_loop …
0xParthP Sep 5, 2026
ecfbff8
refactor: remove unnecessary whitespace and add tests for run_loop fu…
0xParthP Sep 5, 2026
9351d6e
refactor: improve event handling and add key press tests for quitting…
0xParthP Sep 5, 2026
d17a259
feat: enhance AppState with project management and search functionality
0xParthP Sep 6, 2026
a4bb7b8
feat: implement project loading and enhance TUI with project manageme…
0xParthP Sep 6, 2026
d0460ee
feat: add temp-env dependency and enhance project loading with sortin…
0xParthP Sep 6, 2026
1fb781d
feat: implement project opening functionality and enhance TUI with pr…
0xParthP Sep 6, 2026
f3ff842
feat: update default IDE to Vscode across configuration and tests
0xParthP Sep 6, 2026
1854a21
feat: enhance TUI event handling with launcher support for project op…
0xParthP Sep 6, 2026
c58477c
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 6, 2026
ade656c
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 6, 2026
1064aa5
feat: Implement tab navigation and enhance project list rendering in TUI
0xParthP Sep 6, 2026
7f433e6
feat: Add tab navigation tests and enhance UI rendering for tabs in TUI
0xParthP Sep 6, 2026
adcec42
feat: Bump version to 2.0.0 in Cargo.toml and Cargo.lock
0xParthP Sep 6, 2026
d7cb5bf
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 6, 2026
9a3dd76
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 7, 2026
243c081
fix: Update quit key binding from 'q' to 'Esc' in footer widget
0xParthP Sep 7, 2026
3e27da7
feat: implement recent projects feature in TUI
0xParthP Sep 7, 2026
830c08c
Merge branch 'main' into feature/tui
0xParthP Sep 7, 2026
ac0c231
fix: refactor recent widget test to use updated configuration structure
0xParthP Sep 7, 2026
725610e
Merge branches 'feature/tui' and 'feature/tui' of https://github.com/…
0xParthP Sep 7, 2026
ec1ba33
feat: implement base TUI framework with project list, navigation, and…
0xParthP Sep 11, 2026
25b2a97
feat: implement project, recent, and placeholder widgets with shared …
0xParthP Sep 11, 2026
7abf853
feat: implement configuration management, IDE detection, and project …
0xParthP Sep 11, 2026
003155b
Merge branch 'main' into feature/tui
0xParthP Sep 11, 2026
e040dfc
test: implement integration tests for Windows IDE detection and TUI e…
0xParthP Sep 11, 2026
338a8d6
feat: initialize TUI module structure and expose app entry point
0xParthP Sep 11, 2026
26e58f4
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 11, 2026
bc92eaf
Please provide the diff or description of the changes so I can genera…
0xParthP Sep 11, 2026
2fea8b4
fix for sonar
0xParthP Sep 11, 2026
9e8e763
test: add integration tests for onboarding flow and configuration man…
0xParthP Sep 11, 2026
40a6d66
feat: implement interactive onboarding wizard and initial setup tests
0xParthP Sep 11, 2026
9fc0141
fix: for covergae
0xParthP Sep 11, 2026
e48dca3
feat: add interactive onboarding wizard to initialize configuration o…
0xParthP Sep 11, 2026
62f9466
feat: implement TUI event handling, project actions, and unit tests f…
0xParthP Sep 11, 2026
d7d454b
fix: added test to fix sonar
0xParthP Sep 11, 2026
6c96959
feat: add TUI interface with state management, widgets, and tests
0xParthP Sep 15, 2026
3de7e89
feat: implement tree data structure and filtering utilities for TUI p…
0xParthP Sep 15, 2026
871c238
Merge branch 'main' into feature/tui
0xParthP Sep 15, 2026
bdf3716
feat: implement project tree structure for TUI and add Sonar CPD test…
0xParthP Sep 15, 2026
353986e
feat: implement project list widget for TUI
0xParthP Sep 15, 2026
bf13fa1
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 15, 2026
98d1795
feat: add TUI modules for state, events, widgets, themes, and tests
0xParthP Sep 15, 2026
50d01cb
feat: add interactive TUI dashboard, IDE launcher, and associated tests
0xParthP Sep 23, 2026
6a6aae2
feat: implement IDE launcher and TUI application entrypoint with tests
0xParthP Sep 23, 2026
e35cba5
Merge branch 'main' of https://github.com/0xParthP/dev-cli into featu…
0xParthP Sep 23, 2026
ec1ac30
feat: implement TUI event handling, state management, widgets, and co…
0xParthP Sep 23, 2026
79b4305
chore: bump version to 2.1.0
0xParthP Sep 23, 2026
ff845b8
feat: implement TUI dashboard, IDE launcher, configuration management…
0xParthP Sep 25, 2026
2d28662
Merge branch 'main' into feature/tui
0xParthP Sep 25, 2026
6ae8011
test: add unit tests for TUI application state
0xParthP Sep 26, 2026
6825c91
test: add comprehensive unit tests for TUI components and state manag…
0xParthP Sep 26, 2026
1812940
feat: add IDE selection models, TUI theme, and settings widgets
0xParthP Sep 28, 2026
56eeab2
test: add comprehensive unit tests for AppState TUI state management
0xParthP Sep 28, 2026
0831926
feat: add TUI widgets and theme configuration for IDE management
0xParthP Sep 28, 2026
b893da7
feat: add TUI color palette theme and IDE management widget
0xParthP Sep 28, 2026
c2450e8
refactor: simplify IDE detection logic to eliminate duplication
0xParthP Sep 28, 2026
0fe34d0
refactor: extract render_field_spans form input helper to reduce dupl…
0xParthP Sep 28, 2026
f020653
refactor: compact render_entry_row formatting in ide_list widget
0xParthP Sep 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//! CLI argument parsing using Clap derive macros.

use crate::models::ide::Ide;
use crate::models::ide::IdeSelection;
use clap::{Args, Parser, Subcommand};

#[derive(Parser)]
Expand Down Expand Up @@ -39,7 +37,7 @@ pub struct OpenArgs {

/// IDE to use for opening (overrides config default).
#[arg(short, long)]
pub ide: Option<Ide>,
pub ide: Option<IdeSelection>,
}

/// Subcommands for `dev project`.
Expand Down Expand Up @@ -72,7 +70,7 @@ pub enum ConfigSubcommand {
/// Set the default IDE to use when opening projects.
SetDefaultIde {
/// The IDE to set as default.
ide: Ide,
ide: IdeSelection,
},
}

Expand Down
19 changes: 15 additions & 4 deletions src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,29 @@ use crate::{
config::Config,
};

use crate::models::ide::IdeSelection;

/// Execute a configuration command.
pub fn execute(cmd: ConfigCommand) -> Result<()> {
match cmd.command {
ConfigSubcommand::Init => init(),
ConfigSubcommand::Show => show(),
ConfigSubcommand::SetDefaultIde { ide } => {
let detected = crate::ide::detect::detect_ides();
if !detected.iter().any(|i| i.ide == ide) {
anyhow::bail!("IDE '{:?}' is not installed on your system.", ide);
let mut config = Config::load()?;
match &ide {
IdeSelection::BuiltIn(b) => {
let detected = crate::ide::detect::detect_ides();
if !detected.iter().any(|i| i.ide == *b) {
anyhow::bail!("IDE '{:?}' is not installed on your system.", b);
}
}
IdeSelection::Custom(id) => {
if !config.custom_ides.iter().any(|c| c.id == *id) {
anyhow::bail!("Custom IDE '{}' is not configured.", id);
}
}
}

let mut config = Config::load()?;
config.default_ide = ide;
config.save()?;

Expand Down
6 changes: 3 additions & 3 deletions src/commands/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ fn open(args: OpenArgs) -> Result<()> {
bail!("Project '{}' not found.", args.project);
};

let ide = args.ide.unwrap_or(config.default_ide);
let ide = args.ide.unwrap_or_else(|| config.default_ide.clone());

launcher::launch(ide, &project.path)?;
launcher::launch_selection(&ide, &project.path, &config.custom_ides)?;

config.add_recent_project(&project);
config.add_recent_project_with_ide(&project, ide);
config.save()?;

println!("{} {}", "Opened".green(), project.path.display());
Expand Down
106 changes: 100 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,77 @@ use directories::{BaseDirs, ProjectDirs};
use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};

use crate::models::{ide::Ide, project::Project, recent_project::RecentProject};
use crate::models::{
custom_ide::CustomIde,
ide::{Ide, IdeSelection},
project::Project,
recent_project::RecentProject,
};

fn default_max_depth() -> usize {
4
}

fn default_ignore_patterns() -> Vec<String> {
vec![
"node_modules".to_string(),
"target".to_string(),
"vendor".to_string(),
".venv".to_string(),
"venv".to_string(),
"build".to_string(),
"dist".to_string(),
]
}

fn default_theme() -> String {
"neon".to_string()
}

fn default_recent_limit() -> usize {
10
}

fn default_auto_refresh() -> bool {
true
}

/// User configuration for dev-cli.
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
/// Directories to search for Git repositories.
pub projects_root: Vec<PathBuf>,

/// Default IDE used when opening projects.
pub default_ide: Ide,
pub default_ide: IdeSelection,

/// Recently opened projects.
#[serde(default)]
pub recent_projects: Vec<RecentProject>,

/// User-configured custom IDEs.
#[serde(default)]
pub custom_ides: Vec<CustomIde>,

/// Maximum search depth for repository scanner.
#[serde(default = "default_max_depth")]
pub max_depth: usize,

/// Extra directory names to ignore during scanning.
#[serde(default = "default_ignore_patterns")]
pub ignore_patterns: Vec<String>,

/// Active TUI theme palette name ("neon", "cyberpunk", "catppuccin", "monokai", "high-contrast").
#[serde(default = "default_theme")]
pub theme: String,

/// Maximum number of recent projects to retain.
#[serde(default = "default_recent_limit")]
pub recent_projects_limit: usize,

/// Automatically refresh project list when starting the TUI.
#[serde(default = "default_auto_refresh")]
pub auto_refresh_on_launch: bool,
}

impl Default for Config {
Expand All @@ -32,8 +89,14 @@ impl Default for Config {

Self {
projects_root: vec![home.join("Projects")],
default_ide: Ide::Vscode,
default_ide: IdeSelection::BuiltIn(Ide::Vscode),
recent_projects: Vec::new(),
custom_ides: Vec::new(),
max_depth: default_max_depth(),
ignore_patterns: default_ignore_patterns(),
theme: default_theme(),
recent_projects_limit: default_recent_limit(),
auto_refresh_on_launch: default_auto_refresh(),
}
}
}
Expand Down Expand Up @@ -117,10 +180,10 @@ impl Config {
}

pub fn add_recent_project(&mut self, project: &Project) {
self.add_recent_project_with_ide(project, self.default_ide);
self.add_recent_project_with_ide(project, self.default_ide.clone());
}

pub fn add_recent_project_with_ide(&mut self, project: &Project, ide: Ide) {
pub fn add_recent_project_with_ide(&mut self, project: &Project, ide: IdeSelection) {
self.recent_projects.retain(|p| p.path != project.path);

self.recent_projects.insert(
Expand All @@ -135,4 +198,35 @@ impl Config {

self.recent_projects.truncate(10);
}

/// Add a custom IDE to the configuration.
pub fn add_custom_ide(&mut self, ide: CustomIde) {
self.custom_ides.retain(|i| i.id != ide.id);
self.custom_ides.push(ide);
self.custom_ides.sort_by_key(|a| a.display_name.to_lowercase());
}

/// Remove a custom IDE by its identifier.
pub fn remove_custom_ide(&mut self, id: &str) {
self.custom_ides.retain(|i| i.id != id);
}

/// Look up a custom IDE by its identifier.
pub fn get_custom_ide(&self, id: &str) -> Option<&CustomIde> {
self.custom_ides.iter().find(|i| i.id == id)
}

/// Add a project root directory to the configuration.
pub fn add_project_root(&mut self, root: PathBuf) {
if !self.projects_root.contains(&root) {
self.projects_root.push(root);
}
}

/// Remove a project root directory by index.
pub fn remove_project_root(&mut self, index: usize) {
if index < self.projects_root.len() {
self.projects_root.remove(index);
}
}
}
Loading
Loading