Summary
codebase-memory-mcp install and codebase-memory-mcp update ignore the CLAUDE_CONFIG_DIR environment variable and unconditionally write Claude Code skills, MCP entries, hook scripts, and settings.json under $HOME/.claude/.
Users who keep their Claude Code config under a non-default location (e.g. CLAUDE_CONFIG_DIR=$HOME/.config/claude-code, the location Claude Code itself uses on macOS when configured that way) end up with:
- A new
~/.claude/ tree silently created by the installer.
- Their real Claude Code config dir untouched — so the skills/MCP entry/hooks the installer claims it wrote are not visible to Claude Code at runtime.
cbm_detect_agents() checking $HOME/.claude (not CLAUDE_CONFIG_DIR) and reporting Claude Code as "detected" or "not detected" based on the wrong path.
This was first observed during a 0.6.0 → 0.6.1 upgrade.
Reproduce
export CLAUDE_CONFIG_DIR="$HOME/.config/claude-code"
mkdir -p "$CLAUDE_CONFIG_DIR"
codebase-memory-mcp install -y
# Expected: writes under $CLAUDE_CONFIG_DIR
# Actual: writes under $HOME/.claude
ls -la ~/.claude/skills # populated (wrong)
ls -la "$CLAUDE_CONFIG_DIR/skills" # empty / missing (should be populated)
Affected paths
All hardcoded in src/cli/cli.c:
| Line |
Path written |
Function |
cli.c:981 |
${HOME}/.claude |
cbm_detect_agents (detection) |
cli.c:1466 |
~/.claude/hooks/cbm-code-discovery-gate |
CMM_HOOK_COMMAND macro |
cli.c:1650 |
${HOME}/.claude/hooks |
cbm_install_hook_gate_script |
cli.c:1687,1694 |
~/.claude/hooks/... |
session-reminder hook |
cli.c:2629 |
${HOME}/.claude/skills |
install_claude_code_config |
cli.c:2640 |
${HOME}/.claude/.mcp.json |
install MCP |
cli.c:2654 |
${HOME}/.claude/settings.json |
install hooks |
cli.c:2949..2967 |
same paths |
uninstall_claude_code |
Same bug at the shell layer: scripts/setup.sh:212,218, scripts/security-install.sh:124.
Note: hooks installed into ~/.claude/hooks/ already read CLAUDE_CONFIG_DIR correctly at runtime — only the install/uninstall path ignores it.
Proposal
Add a small helper:
static void cbm_claude_config_dir(const char *home, char *out, size_t out_sz) {
const char *env = getenv("CLAUDE_CONFIG_DIR");
if (env && env[0]) {
snprintf(out, out_sz, "%s", env);
} else {
snprintf(out, out_sz, "%s/.claude", home);
}
}
…and route every "%s/.claude..." install/uninstall write through it. Replace CMM_HOOK_COMMAND / CMM_SESSION_COMMAND macro literals with strings composed at install time so settings.json records the actual hook path.
Bundle a one-line stderr migration hint: when the resolved dir differs from $HOME/.claude and a stale ~/.claude install is detected, list legacy artifacts so users can remove them. Bundling this with the fix avoids a two-release rollout where users upgrade, find their config silently moved, and have no nudge to clean up the old tree.
Mirror the change in scripts/setup.sh and scripts/security-install.sh (CLAUDE_HOME="${CLAUDE_CONFIG_DIR:-$HOME/.claude}").
Add a smoke-test case (scripts/smoke-test.sh) asserting that with CLAUDE_CONFIG_DIR set the artifacts land there, not in $FAKE_HOME/.claude.
Out of scope
- Adding a project-local
--scope=project install flag (separate feature gap, future work).
- The Phase-07 plan in some downstream forks targeting a Go installer — that installer is no longer the install path; only the C
install subcommand is in use.
Environment
- macOS, codebase-memory-mcp 0.6.1
CLAUDE_CONFIG_DIR=$HOME/.config/claude-code (Claude Code's own configured location)
Summary
codebase-memory-mcp installandcodebase-memory-mcp updateignore theCLAUDE_CONFIG_DIRenvironment variable and unconditionally write Claude Code skills, MCP entries, hook scripts, andsettings.jsonunder$HOME/.claude/.Users who keep their Claude Code config under a non-default location (e.g.
CLAUDE_CONFIG_DIR=$HOME/.config/claude-code, the location Claude Code itself uses on macOS when configured that way) end up with:~/.claude/tree silently created by the installer.cbm_detect_agents()checking$HOME/.claude(notCLAUDE_CONFIG_DIR) and reporting Claude Code as "detected" or "not detected" based on the wrong path.This was first observed during a 0.6.0 → 0.6.1 upgrade.
Reproduce
Affected paths
All hardcoded in
src/cli/cli.c:cli.c:981${HOME}/.claudecbm_detect_agents(detection)cli.c:1466~/.claude/hooks/cbm-code-discovery-gateCMM_HOOK_COMMANDmacrocli.c:1650${HOME}/.claude/hookscbm_install_hook_gate_scriptcli.c:1687,1694~/.claude/hooks/...cli.c:2629${HOME}/.claude/skillsinstall_claude_code_configcli.c:2640${HOME}/.claude/.mcp.jsoncli.c:2654${HOME}/.claude/settings.jsoncli.c:2949..2967uninstall_claude_codeSame bug at the shell layer:
scripts/setup.sh:212,218,scripts/security-install.sh:124.Note: hooks installed into
~/.claude/hooks/already readCLAUDE_CONFIG_DIRcorrectly at runtime — only the install/uninstall path ignores it.Proposal
Add a small helper:
…and route every
"%s/.claude..."install/uninstall write through it. ReplaceCMM_HOOK_COMMAND/CMM_SESSION_COMMANDmacro literals with strings composed at install time sosettings.jsonrecords the actual hook path.Bundle a one-line stderr migration hint: when the resolved dir differs from
$HOME/.claudeand a stale~/.claudeinstall is detected, list legacy artifacts so users can remove them. Bundling this with the fix avoids a two-release rollout where users upgrade, find their config silently moved, and have no nudge to clean up the old tree.Mirror the change in
scripts/setup.shandscripts/security-install.sh(CLAUDE_HOME="${CLAUDE_CONFIG_DIR:-$HOME/.claude}").Add a smoke-test case (
scripts/smoke-test.sh) asserting that withCLAUDE_CONFIG_DIRset the artifacts land there, not in$FAKE_HOME/.claude.Out of scope
--scope=projectinstall flag (separate feature gap, future work).installsubcommand is in use.Environment
CLAUDE_CONFIG_DIR=$HOME/.config/claude-code(Claude Code's own configured location)