haematite-cli 0.21.3

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
Documentation
use tokio::process::Command;

const INHERITED: &[&str] = &[
    "PATH",
    "HOME",
    "TMPDIR",
    "SHELL",
    "USER",
    "LOGNAME",
    "LANG",
    "LC_ALL",
    "TERM",
    "XDG_CONFIG_HOME",
    "XDG_DATA_HOME",
    "XDG_CACHE_HOME",
    "XDG_STATE_HOME",
    "HTTP_PROXY",
    "HTTPS_PROXY",
    "NO_PROXY",
    "http_proxy",
    "https_proxy",
    "no_proxy",
    "SSL_CERT_FILE",
    "SSL_CERT_DIR",
    "NODE_EXTRA_CA_CERTS",
    "TOKENIZERS_PARALLELISM",
];
// Account and proxy names are the launch renderer's explicit model inputs.
const MODEL_ACCOUNT: &[&str] = &[
    "ANTHROPIC_AUTH_TOKEN",
    "CODEX_API_KEY",
    "LYS_ACCOUNT_VARIABLE",
    "ANTHROPIC_BASE_URL",
    "OPENAI_BASE_URL",
];
const DECLARED_PROVIDER: &[&str] = &[
    "ANTHROPIC_API_KEY",
    "OPENAI_API_KEY",
    "CLAUDE_CODE_OAUTH_TOKEN",
];

pub(super) fn check_provider(names: &[String]) -> anyhow::Result<()> {
    for name in DECLARED_PROVIDER {
        anyhow::ensure!(
            std::env::var_os(name).is_none_or(|value| value.is_empty())
                || names.iter().any(|declared| declared == name),
            "provider_environment_undeclared: {name}"
        );
    }
    Ok(())
}

pub(super) fn validate(names: &[String]) -> anyhow::Result<()> {
    for name in names {
        let upper = name.to_ascii_uppercase();
        anyhow::ensure!(
            !name.is_empty()
                && name.len() <= 128
                && name
                    .bytes()
                    .all(|byte| byte.is_ascii_alphanumeric() || byte == b'_'),
            "environment_name_invalid"
        );
        anyhow::ensure!(
            DECLARED_PROVIDER.contains(&name.as_str())
                || (!["KEY", "TOKEN", "SECRET", "PASSWORD", "CREDENTIAL"]
                    .iter()
                    .any(|part| upper.contains(part))
                    && !["_AUTH", "_PASS", "_PAT", "DATABASE_URL"]
                        .iter()
                        .any(|part| upper.ends_with(part))),
            "credential_environment_refused: {name}"
        );
    }
    Ok(())
}

pub(super) fn apply(command: &mut Command, declared: &[String]) -> anyhow::Result<()> {
    validate(declared)?;
    check_provider(declared)?;
    command.env_clear();
    for name in INHERITED.iter().chain(MODEL_ACCOUNT) {
        if let Some(value) = std::env::var_os(name) {
            command.env(name, value);
        }
    }
    for name in declared {
        let value = std::env::var_os(name)
            .ok_or_else(|| anyhow::anyhow!("environment_declared_but_absent: {name}"))?;
        command.env(name, value);
    }
    command.env_remove("LYS_AGENT_PASS");
    Ok(())
}