Skip to main content

recall_echo/
config_cli.rs

1//! CLI handlers for `recall-echo config show` and `recall-echo config set`.
2
3use std::path::Path;
4
5use crate::config::{self, Provider};
6
7const BOLD: &str = "\x1b[1m";
8const DIM: &str = "\x1b[2m";
9const GREEN: &str = "\x1b[32m";
10const RESET: &str = "\x1b[0m";
11
12/// Display current configuration.
13pub fn show(memory_dir: &Path) -> Result<(), String> {
14    let cfg = config::load(memory_dir);
15    let path = config::config_path(memory_dir);
16    let exists = path.exists();
17
18    eprintln!("{BOLD}recall-echo config{RESET}");
19    if exists {
20        eprintln!("{DIM}{}{RESET}\n", path.display());
21    } else {
22        eprintln!("{DIM}(no config file — using defaults){RESET}\n");
23    }
24
25    // Ephemeral
26    eprintln!("{BOLD}[ephemeral]{RESET}");
27    eprintln!("  max_entries = {}", cfg.ephemeral.max_entries);
28
29    // LLM
30    eprintln!("\n{BOLD}[llm]{RESET}");
31    let provider_label = match &cfg.llm.provider {
32        Provider::Anthropic => "anthropic",
33        Provider::Openai => "openai (ollama)",
34        Provider::ClaudeCode => "claude-code",
35    };
36    eprintln!("  provider = {provider_label}");
37    eprintln!(
38        "  model    = {} {DIM}({}){RESET}",
39        cfg.llm.resolved_model(),
40        if cfg.llm.model.is_empty() {
41            "default"
42        } else {
43            "custom"
44        }
45    );
46    eprintln!(
47        "  api_base = {} {DIM}({}){RESET}",
48        cfg.llm.resolved_api_base(),
49        if cfg.llm.api_base.is_empty() {
50            "default"
51        } else {
52            "custom"
53        }
54    );
55
56    // Pipeline
57    if let Some(ref pipeline) = cfg.pipeline {
58        eprintln!("\n{BOLD}[pipeline]{RESET}");
59        eprintln!(
60            "  docs_dir  = {}",
61            pipeline
62                .docs_dir
63                .as_deref()
64                .unwrap_or("{DIM}(not set){RESET}")
65        );
66        eprintln!("  auto_sync = {}", pipeline.auto_sync.unwrap_or(false));
67    }
68
69    Ok(())
70}
71
72/// Set a config key and save.
73pub fn set(memory_dir: &Path, key: &str, value: &str) -> Result<(), String> {
74    let mut cfg = config::load(memory_dir);
75    cfg.set_key(key, value)?;
76    config::save(memory_dir, &cfg)?;
77
78    eprintln!("{GREEN}✓{RESET} Set {BOLD}{key}{RESET} = {BOLD}{value}{RESET}");
79
80    // Show resolved values after setting provider
81    if key == "llm.provider" || key == "provider" {
82        eprintln!("  model    → {}", cfg.llm.resolved_model());
83        eprintln!("  api_base → {}", cfg.llm.resolved_api_base());
84    }
85
86    Ok(())
87}