vallum 0.8.7

Security boundary between AI coding agents and your shell — redacts secrets, neutralizes prompt injection, sanitizes untrusted terminal output, audits every command.
Documentation
//! Strip ANSI escape sequences (color and cursor-control) from captured output.

use regex::Regex;
use std::sync::OnceLock;

pub fn strip(input: &str) -> String {
    static RE: OnceLock<Regex> = OnceLock::new();
    let re = RE.get_or_init(|| {
        Regex::new(r"\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-Z\\-_]")
            .unwrap()
    });
    re.replace_all(input, "").into_owned()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn strip_basic_color() {
        let input = "\x1b[31mError\x1b[0m: failed";
        assert_eq!(strip(input), "Error: failed");
    }

    #[test]
    fn strip_cursor_move() {
        let input = "line1\x1b[2Aline2";
        assert_eq!(strip(input), "line1line2");
    }

    #[test]
    fn preserve_plain_text() {
        let input = "hello world";
        assert_eq!(strip(input), "hello world");
    }

    use proptest::prelude::*;

    proptest! {
        #[test]
        fn prop_strip_does_not_panic(s in "[\\s\\S]{0,1000}") {
            let _ = strip(&s);
        }

        #[test]
        fn prop_strip_never_grows(s in "[\\s\\S]{0,1000}") {
            let out = strip(&s);
            prop_assert!(out.len() <= s.len());
        }
    }
}