Summary
Follow-up to #373 / PR #374, which made the session history, skills, and spinner-verbs lookups honor CLAUDE_CONFIG_DIR. Two adjacent surfaces still hardcode home-relative paths, and each needs slightly different relocation logic than the shared util.get_claude_config_dir() helper provides, which is why they were excluded from that PR.
Remaining gaps
- User-scope MCP config:
claude_mcp_manager.py line 145 pins Path.home() / ".claude.json". The CLI's default location for this file is the home directory itself (not inside ~/.claude), but when CLAUDE_CONFIG_DIR is set the CLI relocates it to $CLAUDE_CONFIG_DIR/.claude.json. So the path needs branch logic: Path(os.environ["CLAUDE_CONFIG_DIR"]) / ".claude.json" when set, else Path.home() / ".claude.json". Today, on an override deployment, NBI's reads (user-scope servers, disabledMcpServers) hit the wrong file while writes via the inherited-env claude mcp add land in the relocated one, so reads and writes diverge.
- Plugin cache:
plugin_manager.py lines 243-247 fall back to Path.home() / ".claude" / "plugins" (after its own CLAUDE_CODE_PLUGIN_CACHE_DIR override). The CLI keeps the plugin cache under the config dir, so the fallback should be Path(get_claude_config_dir()) / "plugins".
Docs touch-ups to ride along
docs/admin-guide.md (Kubeflow/KubeSpawner persistent-volume note, near the filesystem table): "ensure ~/.jupyter and ~/.claude are inside that mount" deserves a clause covering a CLAUDE_CONFIG_DIR that points outside the home mount.
- The
~/.claude.json / ~/.claude/plugins/ mentions in the admin guide should gain the override note once the code above actually follows it (adding the note first would overclaim).
Refs #373
Summary
Follow-up to #373 / PR #374, which made the session history, skills, and spinner-verbs lookups honor
CLAUDE_CONFIG_DIR. Two adjacent surfaces still hardcode home-relative paths, and each needs slightly different relocation logic than the sharedutil.get_claude_config_dir()helper provides, which is why they were excluded from that PR.Remaining gaps
claude_mcp_manager.pyline 145 pinsPath.home() / ".claude.json". The CLI's default location for this file is the home directory itself (not inside~/.claude), but whenCLAUDE_CONFIG_DIRis set the CLI relocates it to$CLAUDE_CONFIG_DIR/.claude.json. So the path needs branch logic:Path(os.environ["CLAUDE_CONFIG_DIR"]) / ".claude.json"when set, elsePath.home() / ".claude.json". Today, on an override deployment, NBI's reads (user-scope servers,disabledMcpServers) hit the wrong file while writes via the inherited-envclaude mcp addland in the relocated one, so reads and writes diverge.plugin_manager.pylines 243-247 fall back toPath.home() / ".claude" / "plugins"(after its ownCLAUDE_CODE_PLUGIN_CACHE_DIRoverride). The CLI keeps the plugin cache under the config dir, so the fallback should bePath(get_claude_config_dir()) / "plugins".Docs touch-ups to ride along
docs/admin-guide.md(Kubeflow/KubeSpawner persistent-volume note, near the filesystem table): "ensure~/.jupyterand~/.claudeare inside that mount" deserves a clause covering aCLAUDE_CONFIG_DIRthat points outside the home mount.~/.claude.json/~/.claude/plugins/mentions in the admin guide should gain the override note once the code above actually follows it (adding the note first would overclaim).Refs #373