fix(config): support both legacy and new ZEROCLAW_WORKSPACE structure

ZEROCLAW_WORKSPACE can now be either:
- Legacy path: /path/to/workspace (config at /path/to/.zeroclaw/config.toml)
- Parent path: /path/to (config at /path/to/config.toml, workspace at /path/to/workspace)

This maintains backward compatibility with Docker's legacy folder structure
while also supporting the new parent-dir layout.
This commit is contained in:
bhagwan 2026-02-17 23:27:13 -05:00 committed by Chummy
parent da7c21f469
commit b2976eb474

View file

@ -1865,10 +1865,11 @@ pub(crate) fn persist_active_workspace_config_dir(config_dir: &Path) -> Result<(
Ok(())
}
fn resolve_config_dir_for_workspace(workspace_dir: &Path) -> PathBuf {
fn resolve_config_dir_for_workspace(workspace_dir: &Path) -> (PathBuf, PathBuf) {
let workspace_config_dir = workspace_dir.to_path_buf();
let workspace_dir = workspace_dir.join("workspace").to_path_buf();
if workspace_config_dir.join("config.toml").exists() {
return workspace_config_dir;
return (workspace_config_dir, workspace_dir);
}
let legacy_config_dir = workspace_dir
@ -1876,18 +1877,18 @@ fn resolve_config_dir_for_workspace(workspace_dir: &Path) -> PathBuf {
.map(|parent| parent.join(".zeroclaw"));
if let Some(legacy_dir) = legacy_config_dir {
if legacy_dir.join("config.toml").exists() {
return legacy_dir;
return (legacy_dir, workspace_config_dir);
}
if workspace_dir
.file_name()
.is_some_and(|name| name == std::ffi::OsStr::new("workspace"))
{
return legacy_dir;
return (legacy_dir, workspace_config_dir);
}
}
workspace_config_dir
(workspace_config_dir, workspace_dir)
}
fn decrypt_optional_secret(
@ -1934,8 +1935,7 @@ impl Config {
// 3. Default ~/.zeroclaw layout
let (zeroclaw_dir, workspace_dir) = match std::env::var("ZEROCLAW_WORKSPACE") {
Ok(custom_workspace) if !custom_workspace.is_empty() => {
let workspace = PathBuf::from(custom_workspace);
(resolve_config_dir_for_workspace(&workspace), workspace)
resolve_config_dir_for_workspace(&PathBuf::from(custom_workspace))
}
_ => load_persisted_workspace_dirs(&default_zeroclaw_dir)?
.unwrap_or((default_zeroclaw_dir, default_workspace_dir)),
@ -2053,7 +2053,9 @@ impl Config {
// Workspace directory: ZEROCLAW_WORKSPACE
if let Ok(workspace) = std::env::var("ZEROCLAW_WORKSPACE") {
if !workspace.is_empty() {
self.workspace_dir = PathBuf::from(workspace);
let (_, workspace_dir) =
resolve_config_dir_for_workspace(&PathBuf::from(workspace));
self.workspace_dir = workspace_dir;
}
}