* chore: Exclude CLAUDE.md from Cargo.toml

* feat: add callgraph module and integrate into main analysis flow

* feat: enhance CLI with new severity filtering and analysis modes

* feat: update CHANGELOG with recent enhancements and fixes to severity filtering and output handling

* feat: implement state-model dataflow analysis for resource lifecycle and auth state

* feat: enhance diagnostic output formatting and add evidence structure

* feat: implement attack surface ranking for diagnostics with scoring and sorting

* feat: add comprehensive documentation for installation, usage, and rules reference

* feat: add multiple language support for command execution and evaluation endpoints

* feat: implement inline suppression for findings using `nyx:ignore` comments

* feat: add confidence levels to AST patterns and update output structure

* feat: implement low-noise prioritization system with category filtering, rollup grouping, and configurable budgets

* feat: bump version to 0.4.0 and update changelog with new features and improvements

* feat: add dead code allowances to various functions in mod.rs and real_world_tests.rs
This commit is contained in:
Eli Peter 2026-02-25 21:16:36 -05:00 committed by GitHub
parent 19b578c5c4
commit 1bbe4b1cfb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
456 changed files with 25628 additions and 1228 deletions

View file

@ -1,4 +1,4 @@
use clap::{Parser, Subcommand};
use clap::{Parser, Subcommand, ValueEnum};
#[derive(Parser)]
#[command(name = "nyx")]
@ -13,10 +13,55 @@ impl Commands {
/// Whether this command produces structured (machine-readable) output on
/// stdout, meaning human status messages must be suppressed entirely.
pub fn is_structured_output(&self) -> bool {
matches!(self, Commands::Scan { format, .. } if format == "json" || format == "sarif")
matches!(self, Commands::Scan { format, .. } if *format == OutputFormat::Json || *format == OutputFormat::Sarif)
}
}
/// Output format for scan results.
#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum, Default)]
pub enum OutputFormat {
#[default]
Console,
Json,
Sarif,
}
impl std::fmt::Display for OutputFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
OutputFormat::Console => write!(f, "console"),
OutputFormat::Json => write!(f, "json"),
OutputFormat::Sarif => write!(f, "sarif"),
}
}
}
/// Index mode for scan operations.
#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum, Default)]
pub enum IndexMode {
/// Use index if available, build if missing (default)
#[default]
Auto,
/// Skip indexing entirely, scan filesystem directly
Off,
/// Force rebuild index before scanning
Rebuild,
}
/// Analysis mode for scan operations.
#[derive(Debug, Copy, Clone, PartialEq, Eq, ValueEnum, Default)]
pub enum ScanMode {
/// Run all analyses: AST patterns + CFG + taint (default)
#[default]
Full,
/// Run AST pattern queries only (no CFG/taint)
Ast,
/// Run CFG structural analyses + taint only (no AST patterns)
Cfg,
/// Alias for cfg (CFG + taint analysis)
Taint,
}
#[derive(Subcommand)]
pub enum Commands {
/// Scan project for vulnerabilities
@ -25,35 +70,118 @@ pub enum Commands {
#[arg(default_value = ".")]
path: String,
/// Skip using/building index, scan directly
#[arg(long)]
no_index: bool,
/// Index mode: auto (default), off (no index), rebuild (force rebuild)
#[arg(long, value_enum, default_value_t = IndexMode::Auto)]
index: IndexMode,
/// Force rebuild index before scanning
#[arg(long)]
rebuild_index: bool,
/// Output format
#[arg(short, long, value_enum, default_value_t = OutputFormat::Console)]
format: OutputFormat,
/// Output format (console, json, sarif)
#[arg(short, long, default_value = "")]
format: String,
/// Show only high severity issues
/// Severity filter expression: HIGH, HIGH,MEDIUM, or >=MEDIUM
///
/// Filters findings AFTER all severity normalization (e.g. nonprod
/// downgrades). Only findings matching the expression are emitted.
/// Case-insensitive. Shell-quote expressions containing ">".
#[arg(long)]
high_only: bool,
severity: Option<String>,
#[arg(long)]
ast_only: bool,
/// Analysis mode: full (default), ast, cfg, taint
#[arg(long, value_enum, default_value_t = ScanMode::Full)]
mode: ScanMode,
#[arg(long)]
cfg_only: bool,
#[arg(long)]
/// Scan all targets (alias for --mode full)
#[arg(long, hide = true)]
all_targets: bool,
/// Include findings from test/vendor/build paths at original severity
/// (by default these are downgraded)
/// Preserve original severity for test/vendor/build paths
///
/// By default, findings in non-production paths are downgraded by one
/// severity tier. This flag preserves original severity.
#[arg(long, alias = "include-nonprod")]
keep_nonprod_severity: bool,
/// Suppress all human-readable status output
#[arg(long)]
include_nonprod: bool,
quiet: bool,
/// Exit with code 1 if any finding meets or exceeds this severity
///
/// Useful for CI gating. Example: --fail-on HIGH
#[arg(long)]
fail_on: Option<String>,
/// Disable attack-surface ranking (findings are sorted by exploitability by default)
#[arg(long)]
no_rank: bool,
/// Show inline-suppressed findings (dimmed, tagged [SUPPRESSED])
#[arg(long)]
show_suppressed: bool,
/// Show all findings: disables category filtering, rollups, and LOW budgets
#[arg(long = "all")]
show_all: bool,
/// Include Quality findings (excluded by default)
#[arg(long)]
include_quality: bool,
/// Maximum total LOW findings to show
#[arg(long, default_value_t = 20)]
max_low: u32,
/// Maximum LOW findings per file
#[arg(long, default_value_t = 1)]
max_low_per_file: u32,
/// Maximum LOW findings per rule
#[arg(long, default_value_t = 10)]
max_low_per_rule: u32,
/// Number of example locations in rollup findings
#[arg(long, default_value_t = 5)]
rollup_examples: u32,
/// Show all instances for a specific rule (bypasses rollup for that rule)
#[arg(long)]
show_instances: Option<String>,
/// Minimum attack-surface score to include in output
///
/// Findings with a rank score below this threshold are suppressed.
/// Requires ranking to be enabled (has no effect with --no-rank).
/// Example: --min-score 50
#[arg(long)]
min_score: Option<u32>,
/// Minimum confidence level to include in output
///
/// Values: low, medium, high. Findings below this level are dropped.
/// JSON/SARIF include all unless filtered.
#[arg(long)]
min_confidence: Option<String>,
// ── Deprecated aliases (hidden) ─────────────────────────────────
/// Deprecated: use --index off
#[arg(long, hide = true)]
no_index: bool,
/// Deprecated: use --index rebuild
#[arg(long, hide = true)]
rebuild_index: bool,
/// Deprecated: use --severity HIGH
#[arg(long, hide = true)]
high_only: bool,
/// Deprecated: use --mode ast
#[arg(long, hide = true)]
ast_only: bool,
/// Deprecated: use --mode cfg
#[arg(long, hide = true)]
cfg_only: bool,
},
/// Manage project indexes