smart-password-manager-cli 0.1.0

Command line interface for smart password management built on smartpasslib. Generate deterministic passwords from secret phrases without storing them.
use clap::{Parser, Subcommand};

#[derive(Parser, Debug)]
#[command(
    name = "smart-password-manager-cli",
    version,
    about = "Command line interface for smart password management",
    long_about = "Smart Password Manager CLI is a Unix-style utility for managing\n\
                  smart passwords: passwords regenerated on demand from a secret\n\
                  phrase instead of being stored.\n\n\
                  It stores only public keys, descriptions and lengths — never\n\
                  secrets or passwords.\n\n\
                  Author:  Alexander Suvorov\n\
                  License: BSD-3-Clause\n\
                  Repo:    https://github.com/smartlegionlab/smart-password-manager-cli-rs\n\
                  Website: https://smartlegionlab.github.io"
)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Command,
}

#[derive(Subcommand, Debug)]
pub enum Command {
    /// Add a new entry (description, secret phrase, length)
    Add {
        /// Entry description (e.g. "GitHub Account")
        #[arg(short, long)]
        description: Option<String>,

        /// Password length (12–100)
        #[arg(short, long, default_value_t = 16)]
        length: usize,

        /// Secret phrase (min 12 chars). If omitted, prompted interactively.
        #[arg(long)]
        secret: Option<String>,

        /// Read secret phrase from stdin
        #[arg(long)]
        secret_stdin: bool,
    },

    /// Generate the password for an existing entry
    Get {
        /// Public key of the entry (full or short form like "abcd…wxyz")
        #[arg(short, long)]
        key: Option<String>,

        /// Description of the entry (alternative to --key)
        #[arg(short, long)]
        description: Option<String>,

        /// Secret phrase (min 12 chars). If omitted, prompted interactively.
        #[arg(long)]
        secret: Option<String>,

        /// Read secret phrase from stdin
        #[arg(long)]
        secret_stdin: bool,

        /// Copy the password to the system clipboard instead of stdout
        #[arg(long)]
        copy: bool,

        /// Render the password as a QR code in the terminal
        #[arg(long)]
        qr: bool,

        /// Output the password as JSON
        #[arg(long)]
        json: bool,
    },

    /// List all stored entries
    List {
        /// Output as JSON
        #[arg(long)]
        json: bool,
    },

    /// Delete an entry
    Delete {
        /// Public key of the entry
        #[arg(short, long)]
        key: Option<String>,

        /// Description of the entry
        #[arg(short, long)]
        description: Option<String>,

        /// Skip confirmation prompt
        #[arg(short = 'y', long)]
        yes: bool,
    },

    /// Edit an entry's metadata (description and/or length)
    Edit {
        /// Public key of the entry
        #[arg(short, long)]
        key: Option<String>,

        /// Current description of the entry
        #[arg(short, long)]
        description: Option<String>,

        /// New description
        #[arg(long)]
        new_description: Option<String>,

        /// New length (12–100)
        #[arg(long)]
        new_length: Option<usize>,
    },

    /// Verify that a secret phrase matches a stored entry
    Verify {
        /// Public key of the entry
        #[arg(short, long)]
        key: Option<String>,

        /// Description of the entry
        #[arg(short, long)]
        description: Option<String>,

        /// Secret phrase (min 12 chars). If omitted, prompted interactively.
        #[arg(long)]
        secret: Option<String>,

        /// Read secret phrase from stdin
        #[arg(long)]
        secret_stdin: bool,
    },
}