1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use clap::{Parser, Subcommand, ValueEnum};
/// PortForge — Modern cross-platform port inspector & manager for developers
///
/// A developer-first tool that shows what's running on your ports
/// with project detection, Docker integration, health checks, and more.
#[derive(Parser, Debug)]
#[command(
name = "portforge",
author = "Kamba",
version,
about = "⚡ Modern port inspector & manager for developers",
long_about = "PortForge is a fast, cross-platform port inspector and manager.\n\n\
It enriches port listings with project detection, framework info,\n\
git branch status, Docker container mapping, and health checks.\n\n\
Run without arguments to launch the interactive TUI."
)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
/// Show all ports (not just dev projects)
#[arg(short, long, global = true)]
pub all: bool,
/// Output as JSON
#[arg(long, global = true)]
pub json: bool,
/// Output as CSV
#[arg(long, global = true)]
pub csv: bool,
/// Disable colored output
#[arg(long, global = true)]
pub no_color: bool,
/// Enable verbose logging (RUST_LOG=debug)
#[arg(short, long, global = true)]
pub verbose: bool,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
/// Inspect a specific port in detail
Inspect {
/// Port number to inspect
port: u16,
},
/// Kill the process on a given port
Kill {
/// Port number to kill
port: u16,
/// Force kill (SIGKILL instead of SIGTERM)
#[arg(short, long)]
force: bool,
},
/// Clean up orphaned and zombie port processes
Clean {
/// Preview what would be cleaned without actually killing
#[arg(short, long)]
dry_run: bool,
},
/// Launch live-updating watch mode
Watch {
/// Refresh interval in seconds
#[arg(short, long, default_value = "2")]
interval: u64,
},
/// Show htop-style process list filtered to listening ports
Ps,
/// Export port data
Export {
/// Export format
#[arg(short, long, default_value = "json")]
format: ExportFormat,
/// Output file (stdout if not specified)
#[arg(short, long)]
output: Option<String>,
},
/// Find free ports starting from a given port
Free {
/// Starting port number to search from
#[arg(default_value = "3000")]
start: u16,
/// Number of free ports to find
#[arg(short, long, default_value = "1")]
count: usize,
},
/// Detect port conflicts (multiple processes on same port)
Conflicts {
/// Check a specific port
#[arg(short, long)]
port: Option<u16>,
},
/// Launch the web dashboard
#[cfg(feature = "web")]
Serve {
/// Port for the web dashboard
#[arg(short, long, default_value = "9090")]
port: u16,
/// Bind address
#[arg(short, long, default_value = "127.0.0.1")]
bind: String,
},
/// Generate default configuration file
InitConfig,
}
#[derive(Debug, Clone, ValueEnum)]
pub enum ExportFormat {
Json,
Csv,
}