Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions cupcake-cli/src/harness_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,16 @@ impl HarnessConfig for ClaudeHarness {

fn settings_path(&self, global: bool) -> PathBuf {
if global {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("~"))
.join(".claude")
// Honor CLAUDE_CONFIG_DIR (Claude Code's config relocation env var);
// fall back to ~/.claude when unset.
std::env::var_os("CLAUDE_CONFIG_DIR")
.filter(|dir| !dir.is_empty())
.map(PathBuf::from)
.unwrap_or_else(|| {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("~"))
.join(".claude")
})
.join("settings.json")
} else {
Path::new(".claude").join("settings.json")
Expand Down Expand Up @@ -789,6 +796,27 @@ mod tests {
assert_eq!(existing["hooks"]["PreToolUse"][0]["matcher"], "*");
}

#[test]
fn test_claude_global_settings_path_respects_config_dir() {
// CLAUDE_CONFIG_DIR set -> path rooted there, not ~/.claude.
std::env::set_var("CLAUDE_CONFIG_DIR", "/custom/claude/dir");
let path = ClaudeHarness.settings_path(true);
assert_eq!(path, PathBuf::from("/custom/claude/dir/settings.json"));

// Unset -> falls back to ~/.claude.
std::env::remove_var("CLAUDE_CONFIG_DIR");
let fallback = ClaudeHarness.settings_path(true);
assert!(fallback.ends_with(".claude/settings.json"));

// Project (non-global) path is unaffected by the env var.
std::env::set_var("CLAUDE_CONFIG_DIR", "/custom/claude/dir");
assert_eq!(
ClaudeHarness.settings_path(false),
PathBuf::from(".claude/settings.json")
);
std::env::remove_var("CLAUDE_CONFIG_DIR");
}

#[test]
fn test_duplicate_detection() {
let mut existing = json!({
Expand Down