Skip to main content

agent_image_diff/
cli.rs

1use clap::{Parser, ValueEnum};
2use std::path::PathBuf;
3
4const HELP_TEMPLATE: &str = "\
5{bin} - {about}
6
7Usage: {usage}
8
9Arguments:
10  <BASELINE>                 Path to the baseline (expected) image
11  <CANDIDATE>                Path to the candidate (actual) image
12
13Output:
14  -f, --format <FORMAT>      Output format: json, summary, image [default: json]
15  -o, --output <PATH>        Write visual diff image (works alongside any format)
16  -v, --verbose              Include all diagnostic fields in JSON
17      --pretty               Pretty-print JSON output
18  -q, --quiet                Suppress stdout; check JSON output for results
19
20Tuning:
21  -t, --threshold <FLOAT>    Color difference sensitivity, 0.0-1.0 [default: 0.1]
22      --denoise <N>          Remove noise clusters smaller than N pixels [default: 25]
23      --dilate <N>           Expand diff mask by N pixels [default: 0]
24      --merge-distance <N>   Merge regions within N pixels of each other [default: 50]
25      --min-region-size <N>  Filter out regions smaller than N pixels [default: 25]
26      --connectivity <N>     Pixel connectivity: 4 (cross) or 8 (diagonals) [default: 8]
27      --detect-antialias     Ignore anti-aliased edge pixels [default: true]
28
29Options:
30  -h, --help                 Print help
31  -V, --version              Print version
32
33Examples:
34  {bin} baseline.png candidate.png
35  {bin} baseline.png candidate.png -v --pretty
36  {bin} baseline.png candidate.png -o diff.png
37  {bin} baseline.png candidate.png -q -o diff.png";
38
39#[derive(Parser)]
40#[command(
41    name = "agent-image-diff",
42    version,
43    about = "structured image diff with JSON output for agent workflows",
44    help_template = HELP_TEMPLATE,
45)]
46pub struct Cli {
47    /// Path to the baseline (expected) image
48    pub baseline: PathBuf,
49
50    /// Path to the candidate (actual) image
51    pub candidate: PathBuf,
52
53    /// Output format (written to stdout)
54    #[arg(short = 'f', long, default_value = "json", value_enum, hide = true)]
55    pub format: OutputFormat,
56
57    /// Path to write visual diff image (works alongside any output format)
58    #[arg(short = 'o', long = "output", hide = true)]
59    pub output: Option<PathBuf>,
60
61    /// Color difference threshold (0.0 = exact match, 1.0 = everything matches)
62    #[arg(short = 't', long, default_value = "0.1", hide = true)]
63    pub threshold: f64,
64
65    /// Enable anti-aliasing detection (reduces false positives at edges)
66    #[arg(long, default_value = "true", hide = true)]
67    pub detect_antialias: bool,
68
69    /// Minimum region size in pixels (regions smaller than this are filtered out)
70    #[arg(long, default_value = "25", hide = true)]
71    pub min_region_size: u32,
72
73    /// Connectivity for region clustering: 4 (cross) or 8 (including diagonals)
74    #[arg(long, default_value = "8", hide = true)]
75    pub connectivity: u8,
76
77    /// Remove noise clusters smaller than this many pixels before dilation (0 = disabled)
78    #[arg(long, default_value = "25", hide = true)]
79    pub denoise: u32,
80
81    /// Dilation radius in pixels (expands diff mask to merge nearby changes, 0 = disabled)
82    #[arg(long, default_value = "0", hide = true)]
83    pub dilate: u32,
84
85    /// Max gap in pixels between regions to merge them (0 = disabled)
86    #[arg(long, default_value = "50", hide = true)]
87    pub merge_distance: u32,
88
89    /// Include all diagnostic fields in JSON output (dimensions, pixel counts, deltas)
90    #[arg(short = 'v', long, hide = true)]
91    pub verbose: bool,
92
93    /// Pretty-print JSON output (default is compact single-line)
94    #[arg(long, hide = true)]
95    pub pretty: bool,
96
97    /// Suppress stdout output
98    #[arg(short = 'q', long, hide = true)]
99    pub quiet: bool,
100}
101
102#[derive(ValueEnum, Clone)]
103pub enum OutputFormat {
104    Json,
105    Image,
106    Summary,
107}