evault-tui 0.1.0

Terminal user interface for evault.
Documentation

evault-tui

crates.io docs.rs License: MIT

Terminal user interface for evault, built on ratatui. Plug any backend that implements VarProvider + VarMutator and get a full dashboard with CRUD, link-to-project, view-value, fuzzy filter, and run-in-project flows.

The crate is intentionally decoupled from any storage layer: the TUI reads rows from a caller-supplied [VarProvider] and writes through [VarMutator]. The same TUI can drive a SQLCipher-backed registry, an in-memory test stub, or a remote facade.

Features

  • Dashboard table with sortable columns: name, group, kind, value length, linked projects, last update.
  • CRUDn new variable, e edit value, d delete (with confirm modal).
  • Link to projectl opens a modal capturing project path + profile + materialize toggle.
  • View valuev reveals the decrypted secret in a centered modal.
  • Run in projectR launches a child process with the project's env injected, no .env on disk.
  • Fuzzy filterCtrl+F opens a centered fuzzy-input powered by nucleo-matcher.
  • Error modals — failed actions surface in a centered modal with a plain-English hint explaining the failure and how to recover.
  • Themable via the Theme struct.

Install

[dependencies]
evault-tui = "0.1"
evault-core = "0.1"
secrecy = "0.10"

Example: launch the TUI against an in-memory backend

use std::path::PathBuf;
use evault_core::model::VarId;
use evault_tui::{run_tui, ProviderError, VarDraft, VarMutator, VarProvider, VarSummary};
use secrecy::SecretString;

struct EmptyBackend;

impl VarProvider for EmptyBackend {
    fn list(&self) -> Result<Vec<VarSummary>, ProviderError> { Ok(Vec::new()) }
    fn get_value(&self, _id: VarId) -> Result<Option<SecretString>, ProviderError> {
        Ok(None)
    }
}

impl VarMutator for EmptyBackend {
    fn delete(&self, _id: VarId) -> Result<(), ProviderError> { Ok(()) }
    fn create(&self, _draft: VarDraft) -> Result<VarId, ProviderError> {
        Ok(VarId::new_v4())
    }
    fn update_value(&self, _id: VarId, _value: SecretString) -> Result<(), ProviderError> {
        Ok(())
    }
    fn link_to_project(
        &self,
        _var_id: VarId,
        _var_name: String,
        _project_path: PathBuf,
        _profile: String,
        _materialize: bool,
    ) -> Result<(), ProviderError> { Ok(()) }
    fn run_in_project(
        &self,
        _project_path: PathBuf,
        _profile: String,
        _program: String,
        _args: Vec<String>,
    ) -> Result<Option<i32>, ProviderError> { Ok(Some(0)) }
}

run_tui(EmptyBackend).unwrap();

Terminal lifecycle

run_tui owns the terminal lifecycle: it enters raw mode + the alternate screen, installs a panic hook that restores them on unwind, and guarantees the restore happens whether the loop returns Ok, returns Err, or panics. For the run-in-project flow specifically, the TUI restores the terminal before spawning the child (so the child inherits a normal terminal with stdio passthrough) and re-enters raw mode after the child exits.

Part of the evault workspace

Used by the evault CLI as the default action when invoked without a subcommand. See the workspace README for the full feature set and keymap.

License

MIT