fix(claude): honor CLAUDE_CONFIG_DIR when listing session history#374
Merged
Merged
Conversation
mbektas
approved these changes
Jun 16, 2026
The Claude CLI relocates its entire config dir, including session transcripts under projects/, when CLAUDE_CONFIG_DIR is set. The session pickers always read ~/.claude/projects, so on deployments that set the override (JupyterHub images commonly point it at a persistent volume) both pickers came up empty even though 'claude --resume' saw every session. Resolve the CLI's config dir through one shared util helper and make it the claude_home default for get_sessions_dir and list_all_sessions. The skills directory and spinner-verbs lookups already carried their own copies of the same expression; they now use the helper too, so the override semantics can't drift between surfaces. The helper deliberately does not expanduser the env value (the CLI doesn't) and treats an empty string as unset (matching the CLI's Node-style falsy check). The MCP user config (~/.claude.json) and the plugin cache have the same class of gap but need different relocation logic; tracked separately. Fixes plmbr#373
85908ce to
e0a9fd5
Compare
Collaborator
Author
|
Resolved conflicts. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Claude CLI relocates its entire config dir, including the session transcripts under
projects/, whenCLAUDE_CONFIG_DIRis set. NBI's session history surfaces (the chat-sidebar resume picker and the launcher tile's session list) always read~/.claude/projects, so on deployments that set the override (JupyterHub images commonly point it at a persistent volume, e.g./home/jovyan/workspace/.claude) both pickers came up empty even thoughclaude --resumesaw every session.Solution
The load-bearing change is in
claude_sessions.py:get_sessions_dirandlist_all_sessionsnow defaultclaude_hometo a newutil.get_claude_config_dir()helper (CLAUDE_CONFIG_DIRwhen set, else~/.claude) instead of a hardcodedPath.home() / ".claude". The skills directory (config.py) and spinner-verbs lookup (extension.py) already carried their own inline copies of the same expression; they now route through the helper too, so the override semantics cannot drift between surfaces.Two deliberate choices, both verified against the CLI's behavior: the helper does not
expanduserthe env value (the CLI doesn't expand~either, so a literal-tilde value should fail identically in both), and an empty string counts as unset (matching the CLI's Node-style falsy check). The docs filesystem table and the troubleshooting diagnostic listing now mention the override, sincels ~/.claude/projects/is exactly the misleading step on an affected deployment.Testing
tests/test_claude_sessions.py(TestClaudeConfigDirDefault):get_sessions_dirhonors the env var and falls back to the home dir (HOME and USERPROFILE both pinned, so the assertion holds on POSIX and Windows);list_all_sessionsdiscovers transcripts under$CLAUDE_CONFIG_DIR/projectswith noclaude_homeargument (the exact production call shape); and a negative test proving~/.claudeis not consulted when the override is set. All existing tests passclaude_homeexplicitly, so the suite stays insulated from a developer's exportedCLAUDE_CONFIG_DIR(verified by running the full file with a junk value exported).tsc --noEmit,lint:check, jest (352).CLAUDE_CONFIG_DIRpointing at a synthetic transcript store;GET /notebook-intelligence/claude-sessionsreturned exactly the synthetic session for bothscope=allandscope=cwd, and none of the real sessions in the actual~/.claude/projects, confirming the override replaces the home dir the same way the CLI does.os.environ, so NBI-created Claude sessions land in the same override dir the picker now reads, and Jupyter terminals inherit the server env, so the generatedclaude --resumecommand finds them.Risks / follow-ups
CLAUDE_CONFIG_DIRis unset: the helper's fallback is the same~/.claudepath as before (viaexpanduser, whichPath.home()also uses).claude_mcp_manager.pyreads~/.claude.json(the CLI moves that file inside$CLAUDE_CONFIG_DIRwhen set, but its default location is the home dir itself, not~/.claude), andplugin_manager.pyfalls back to~/.claude/pluginsfor the plugin cache.Fixes #373