vios_app 0.1.1

Small JSON vaults: Argon2id + AES-GCM, with optional AAD binding.
Documentation
use std::path::Path;
// src/bin/vault_writer_main.rs
use std::io::{self, Read};

use chrono::Utc;
use clap::Parser;

// lib.rs re-exports encrypt_vault, but we also need the payload types
use vios_core::vault::vault_structs::{VaultMetadata, VaultPayload};

/// VIOS Vault Writer — encrypts plaintext into a .vault file.
#[derive(Parser, Debug)]
#[command(author, version, about = "VIOS Vault Writer")]
struct Args {
    /// Output path (e.g. vault_dev_log/demo.vault)
    #[arg(long)]
    out: String,

    /// Password used to encrypt
    #[arg(long)]
    password: String,

    /// Optional creator name (defaults to current user)
    #[arg(long)]
    creator: Option<String>,

    /// Optional plaintext content; if omitted, reads from STDIN
    #[arg(long)]
    content: Option<String>,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args = Args::parse();

    // 1) Gather plaintext
    let plaintext = match args.content {
        Some(s) => s,
        None => {
            let mut buf = String::new();
            io::stdin().read_to_string(&mut buf)?;
            if buf.trim().is_empty() {
                return Err("No --content provided and STDIN was empty.".into());
            }
            buf
        }
    };

    // 2) Build minimal metadata that matches your struct
    let creator = args
        .creator
        .unwrap_or_else(|| whoami::realname().trim().to_string());

    let metadata = VaultMetadata {
        creator_name: creator,
        created_at: Utc::now().to_rfc3339(),
        system_fingerprint: whoami::fallible::hostname()
            .unwrap_or_else(|_| "unknown-host".to_string()),
        tone_classification: None,
        intent_classification: None,
        reem_code: None,
        cia_hash: None,
    };

    // 3) Assemble payload (mirror creator_name at top level for compatibility)
    let payload = VaultPayload {
        content: plaintext,
        creator_name: metadata.creator_name.clone(),
        metadata,
    };

    // 4) Ensure parent dir exists
    if let Some(parent) = Path::new(&args.out).parent() {
        if !parent.as_os_str().is_empty() {
            std::fs::create_dir_all(parent)?;
        }
    }

    // 5) Encrypt
    {
        let bytes = serde_json::to_vec(&payload)?;
        vios_core::vault::vault_crypto::write_vault_v2_file(
            std::path::Path::new(&args.out),
            &args.password,
            &bytes,
        )?;
    }

    eprintln!("✅ Wrote vault: {}", &args.out);
    Ok(())
}