Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion docs/remote-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ soroban-debug server --host 10.0.0.15 --port 9229 \

### Connect from a client


```bash
soroban-debug remote \
--remote localhost:9229 \
--token "$SOROBAN_DEBUG_TOKEN" \
Expand Down
114 changes: 12 additions & 102 deletions src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,6 @@ pub enum SnapshotCompression {
Zstd,
}

/// Minimum severity level for security findings.
/// Used with the `analyze` command to filter results by severity.
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Default)]
pub enum MinSeverity {
#[default]
Low,
Medium,
High,
}

impl Verbosity {
/// Convert verbosity to log level string for RUST_LOG
pub fn to_log_level(self) -> String {
Expand Down Expand Up @@ -160,10 +150,6 @@ pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,

/// Pretty-print JSON outputs instead of compact JSON
#[arg(long, global = true)]
pub pretty: bool,

/// Show detailed version information
#[arg(long)]
pub version_verbose: bool,
Expand Down Expand Up @@ -248,6 +234,13 @@ pub enum Commands {
Server(ServerArgs),

/// Connect to remote debug server
///
/// Examples:
/// soroban-debug remote --remote localhost:9229 --token "$TOKEN"
/// soroban-debug remote --remote 10.0.0.15:9229 --token "$TOKEN" --tls-ca /path/to/server-ca.pem
///
/// For TLS and connection issues, see the remote troubleshooting guide:
/// https://github.com/Timi16/soroban-debugger/blob/main/docs/remote-troubleshooting.md
#[command(subcommand_help_heading = "Remote and Server")]
Remote(RemoteArgs),

Expand Down Expand Up @@ -773,7 +766,7 @@ pub struct OptimizeArgs {

#[cfg(test)]
mod tests {
use super::{Cli, Commands, OutputFormat, SymbolicProfile, MinSeverity};
use super::{Cli, Commands, OutputFormat, SymbolicProfile};
use clap::Parser;

#[test]
Expand Down Expand Up @@ -1058,24 +1051,7 @@ mod tests {
assert_eq!(args.contract.to_str().unwrap(), "contract.wasm");
assert_eq!(args.network_snapshot.unwrap().to_str().unwrap(), "state.json");
}

#[test]
fn replay_accepts_format_flag() {
let cli = Cli::parse_from([
"soroban-debug",
"replay",
"trace.json",
"--format",
"json",
]);

let Commands::Replay(args) = cli.command.expect("replay command expected") else {
panic!("replay command expected");
};

assert_eq!(args.format, OutputFormat::Json);
assert_eq!(args.trace_file.to_str().unwrap(), "trace.json");
}
}
}

#[derive(Parser)]
Expand All @@ -1101,10 +1077,6 @@ pub struct CompareArgs {
/// Repeatable. Useful for timestamps, sequence numbers, and similar metadata.
#[arg(long, value_name = "FIELD")]
pub ignore_field: Vec<String>,

/// Output format for the comparison report (pretty or json)
#[arg(long, value_enum, default_value_t = OutputFormat::Pretty)]
pub format: OutputFormat,
}

/// Arguments for the TUI dashboard subcommand
Expand Down Expand Up @@ -1281,17 +1253,9 @@ pub struct ReplayArgs {
#[arg(short, long)]
pub output: Option<PathBuf>,

/// Output format for replay command (pretty, json)
#[arg(long, value_enum, default_value_t = OutputFormat::Pretty)]
pub format: OutputFormat,

/// Show verbose output during replay
#[arg(short, long)]
pub verbose: bool,

/// Output format for the diff report (pretty or json)
#[arg(long, value_enum, default_value_t = OutputFormat::Pretty)]
pub format: OutputFormat,
}

#[derive(Parser)]
Expand All @@ -1308,12 +1272,6 @@ pub struct ServerArgs {
#[arg(short, long)]
pub token: Option<String>,

/// Enforce the token-strength policy: reject startup if the auth token is
/// shorter than 16 characters instead of only warning. Recommended in
/// production; a random 32-byte token is ideal.
#[arg(long)]
pub require_strong_token: bool,

/// TLS certificate file path (optional)
#[arg(long)]
pub tls_cert: Option<PathBuf>,
Expand Down Expand Up @@ -1424,32 +1382,22 @@ pub struct RemoteArgs {

/// Maximum number of retry attempts for idempotent requests (ping, inspect, storage).
///
/// Must be at least 1. Use 1 to disable retries entirely (one attempt, no retry).
///
/// Default: 3.
#[arg(long, value_name = "N", default_value = "3")]
pub retry_attempts: usize,

/// Base delay in milliseconds between retry attempts (exponential back-off).
///
/// Must be greater than 0 and no larger than --retry-max-delay-ms.
///
/// Default: 200 ms.
#[arg(long, value_name = "MS", default_value = "200")]
pub retry_base_delay_ms: u64,

/// Maximum delay in milliseconds between retry attempts.
///
/// Must be greater than or equal to --retry-base-delay-ms.
///
/// Default: 2 000 ms.
#[arg(long, value_name = "MS", default_value = "2000")]
pub retry_max_delay_ms: u64,

/// Output format for remote command (pretty, json)
#[arg(long, value_enum, default_value_t = OutputFormat::Pretty)]
pub format: OutputFormat,

/// Remote operation to perform (default: execute or ping)
#[command(subcommand)]
pub action: Option<RemoteAction>,
Expand All @@ -1461,21 +1409,10 @@ pub enum RemoteAction {
Inspect,

/// Get contract storage state as JSON
Storage(RemoteStorageArgs),
Storage,

/// Evaluate an expression in the current debug context
Evaluate(RemoteEvaluateArgs),

/// Run a preflight check: connect, handshake, auth, and optional TLS validation
/// without loading a contract. Suitable for CI health checks and troubleshooting.
Preflight(PreflightArgs),
}

#[derive(Parser)]
pub struct PreflightArgs {
/// Output format (pretty or json)
#[arg(long = "output", value_enum, default_value_t = OutputFormat::Pretty)]
pub output_format: OutputFormat,
}

#[derive(Parser)]
Expand All @@ -1489,16 +1426,6 @@ pub struct RemoteEvaluateArgs {
pub frame_id: Option<u64>,
}

#[derive(Parser)]
pub struct RemoteStorageArgs {
/// Filter storage output by key pattern (repeatable). Supports:
/// prefix* — match keys starting with prefix
/// re:<regex> — match keys by regex
/// exact_key — match key exactly
#[arg(long, value_name = "PATTERN")]
pub storage_filter: Vec<String>,
}

#[derive(Parser)]
pub struct AnalyzeArgs {
/// Path to the contract WASM file
Expand Down Expand Up @@ -1534,8 +1461,8 @@ pub struct AnalyzeArgs {
pub disable_rule: Vec<String>,

/// Minimum severity to include: low, medium, or high.
#[arg(long, value_enum, default_value_t = MinSeverity::Low)]
pub min_severity: MinSeverity,
#[arg(long, default_value = "low", value_name = "SEVERITY")]
pub min_severity: String,
}

#[derive(Parser)]
Expand Down Expand Up @@ -1589,20 +1516,3 @@ pub struct DoctorArgs {
#[arg(long, value_name = "FILE")]
pub vscode_manifest: Option<PathBuf>,
}

#[derive(Parser, Debug, Clone)]
pub struct PluginTrustReportArgs {
/// Output format (pretty, json)
#[arg(long, value_enum, default_value = "pretty")]
pub format: OutputFormat,
}

#[derive(Parser, Debug, Clone)]
pub struct PluginInspectArgs {
/// Name of the plugin to inspect
pub name: String,

/// Output format (pretty, json)
#[arg(long, value_enum, default_value = "pretty")]
pub format: OutputFormat,
}
4 changes: 3 additions & 1 deletion tests/parity_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ fn parity_cli_remote_command_flags_exist() {
.assert()
.success()
.stdout(predicate::str::contains("--remote"))
.stdout(predicate::str::contains("--token"));
.stdout(predicate::str::contains("--token"))
.stdout(predicate::str::contains("--tls-ca"))
.stdout(predicate::str::contains("server-ca.pem"));
}

/// SURFACE: CLI only
Expand Down
Loading