tsafe-tui 1.0.10

Terminal UI for tsafe secret vault — full-screen browser with keyboard navigation, history viewer, quick-unlock
Documentation
//! Opt-in TUI diagnostics. Set `TSAFE_TUI_DEBUG=1` (any non-empty value except `0` / `false`).
//! Appends timestamped lines to `app_state_dir()/tui-debug.log` — **never** writes vault passwords
//! or keychain payloads.

use std::fs::OpenOptions;
use std::io::Write;
use std::path::PathBuf;

fn compute_enabled() -> bool {
    match std::env::var("TSAFE_TUI_DEBUG") {
        Ok(v) => {
            let t = v.trim();
            !t.is_empty() && t != "0" && !t.eq_ignore_ascii_case("false")
        }
        Err(_) => false,
    }
}

/// Whether debug logging is active.
pub fn enabled() -> bool {
    compute_enabled()
}

pub fn log_file_path() -> PathBuf {
    tsafe_core::profile::app_state_dir().join("tui-debug.log")
}

/// Append one line. No-op if [`enabled`] is false.
pub fn log(line: impl AsRef<str>) {
    if !enabled() {
        return;
    }
    let path = log_file_path();
    if let Some(parent) = path.parent() {
        let _ = std::fs::create_dir_all(parent);
    }
    let Ok(mut f) = OpenOptions::new().create(true).append(true).open(&path) else {
        return;
    };
    let ts = chrono::Utc::now().format("%Y-%m-%dT%H:%M:%S%.3fZ");
    let _ = writeln!(f, "[{ts}] {}", line.as_ref());
    let _ = f.flush();
}

/// Print log path to stderr before the terminal goes into raw mode.
pub fn announce_if_enabled() {
    if enabled() {
        eprintln!(
            "tsafe TUI debug: appending to {} (unset TSAFE_TUI_DEBUG to disable)",
            log_file_path().display()
        );
    }
}