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