fix(config): check ZEROCLAW_WORKSPACE before loading config

- Move ZEROCLAW_WORKSPACE check to the start of load_or_init()
- Use custom workspace for both config and workspace directories
- Fixes issue where env var was applied AFTER config loading

Fixes #417

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
argenis de la rosa 2026-02-16 18:11:04 -05:00 committed by Chummy
parent 23db125971
commit 75c18ad256

View file

@ -1625,16 +1625,34 @@ impl Default for Config {
impl Config { impl Config {
pub fn load_or_init() -> Result<Self> { pub fn load_or_init() -> Result<Self> {
let home = UserDirs::new() // Check ZEROCLAW_WORKSPACE first, before determining config path
.map(|u| u.home_dir().to_path_buf()) let (zeroclaw_dir, workspace_dir) =
.context("Could not find home directory")?; if let Ok(custom_workspace) = std::env::var("ZEROCLAW_WORKSPACE") {
let zeroclaw_dir = home.join(".zeroclaw"); if !custom_workspace.is_empty() {
let workspace = PathBuf::from(&custom_workspace);
let config_dir = workspace.join(".zeroclaw");
(config_dir, workspace)
} else {
// Fall through to default if empty
let home = UserDirs::new()
.map(|u| u.home_dir().to_path_buf())
.context("Could not find home directory")?;
let default_dir = home.join(".zeroclaw");
(default_dir.clone(), default_dir.join("workspace"))
}
} else {
let home = UserDirs::new()
.map(|u| u.home_dir().to_path_buf())
.context("Could not find home directory")?;
let default_dir = home.join(".zeroclaw");
(default_dir.clone(), default_dir.join("workspace"))
};
let config_path = zeroclaw_dir.join("config.toml"); let config_path = zeroclaw_dir.join("config.toml");
if !zeroclaw_dir.exists() { if !zeroclaw_dir.exists() {
fs::create_dir_all(&zeroclaw_dir).context("Failed to create .zeroclaw directory")?; fs::create_dir_all(&zeroclaw_dir).context("Failed to create .zeroclaw directory")?;
fs::create_dir_all(zeroclaw_dir.join("workspace")) fs::create_dir_all(&workspace_dir).context("Failed to create workspace directory")?;
.context("Failed to create workspace directory")?;
} }
if config_path.exists() { if config_path.exists() {
@ -1644,13 +1662,13 @@ impl Config {
toml::from_str(&contents).context("Failed to parse config file")?; toml::from_str(&contents).context("Failed to parse config file")?;
// Set computed paths that are skipped during serialization // Set computed paths that are skipped during serialization
config.config_path = config_path.clone(); config.config_path = config_path.clone();
config.workspace_dir = zeroclaw_dir.join("workspace"); config.workspace_dir = workspace_dir;
config.apply_env_overrides(); config.apply_env_overrides();
Ok(config) Ok(config)
} else { } else {
let mut config = Config::default(); let mut config = Config::default();
config.config_path = config_path.clone(); config.config_path = config_path.clone();
config.workspace_dir = zeroclaw_dir.join("workspace"); config.workspace_dir = workspace_dir;
config.save()?; config.save()?;
config.apply_env_overrides(); config.apply_env_overrides();
Ok(config) Ok(config)