fix: auto-discover sessions from multiple CLAUDE_CONFIG_DIR paths#36
fix: auto-discover sessions from multiple CLAUDE_CONFIG_DIR paths#36tbouquet wants to merge 3 commits intograykode:mainfrom
Conversation
Users running multiple Claude Code configurations (e.g. personal and enterprise plans via CLAUDE_CONFIG_DIR aliases) only see sessions from one config directory. abtop now discovers all active config directories automatically by reading /proc/<pid>/environ for each running Claude process, in addition to the default ~/.claude and any CLAUDE_CONFIG_DIR set in abtop's own environment. Changes: - ClaudeCollector now maintains a dynamic list of config directories, refreshed each tick from running Claude process environments - find_transcript searches across all discovered project directories - rate_limit reader checks all known config dirs for rate limit files - /proc environ reader with cfg(target_os = "linux") gate and non-Linux stub for cross-platform compatibility Closes graykode#12
Pre-existing code flagged by newer Rust toolchain in CI.
graykode
left a comment
There was a problem hiding this comment.
Thanks so much for tackling this! The /proc/<pid>/environ approach is a really nice way to solve the multi-alias workflow from #12 — much better than requiring abtop itself to know about every config dir ahead of time.
A few thoughts I had while reading through, mostly small:
1. Iteration order of config_dirs
config_dirs is built from a HashSet, so the order isn't stable across runs. I think this could subtly affect two spots:
- In
find_transcript, a worktree-fallback match in one dir could shadow an exact encoded-cwd match in another dir, depending on order. Splitting it into two passes (try encoded-cwd across all dirs first, then the fallback scan across all dirs) would make this deterministic. load_session's fallback picksconfig_dirs.first(), which ends up being effectively random.
Switching to BTreeSet<PathBuf> or a Vec + .contains() should cover both.
2. Scope of Closes #12
Session discovery is definitely fixed, but rate_limit.rs still only reads from abtop's own CLAUDE_CONFIG_DIR + ~/.claude, so the QUOTA half of #12 (where @hmenzagh originally reported the quota column staying empty) isn't fully addressed yet. Totally fine either way — either threading the discovered config dirs through to read_rate_limits, or switching Closes #12 to Refs #12 and leaving quota for a follow-up works for me.
3. macOS coverage note
abtop ships for both Linux and macOS (aarch64/x86_64 each). On macOS the stub returns None, so discovery falls back to abtop's own env var — essentially the v0.2.6 behavior. The PR builds cleanly everywhere, which is great, but if the original reporter happens to be on macOS, they wouldn't see an improvement yet. Could you add a line to the Limitations section making this explicit? A macOS version via sysctl kern.procargs2 would be a nice follow-up but definitely out of scope here.
Nice-to-haves (not blockers)
- Moving
refresh_config_dirsto the slow poll tick would be consistent with how git stats / ports are handled. - A small unit test for
read_env_var_from_proccovering the NUL-separated parsing and the "var not set" case would be nice.
Again, really appreciate the work here — the direction is exactly right. Happy to merge once the first point is addressed; the rest can be follow-ups if you'd rather.
Summary
Fixes #12 - abtop now automatically discovers sessions from all active Claude Code config directories, not just one.
Problem
Users running multiple Claude Code configurations (e.g.
~/.claudefor personal,~/.claude-profor enterprise viaCLAUDE_CONFIG_DIRaliases) only see sessions from whichever single directory abtop happens to resolve at startup. The currentCLAUDE_CONFIG_DIRsupport (added in v0.2.6) requires abtop itself to have the variable set, which doesn't work when multiple instances use different values.Solution
Instead of reading
CLAUDE_CONFIG_DIRfrom abtop's own environment, discover it dynamically from each running Claude process:/proc/<pid>/environfor every detected Claude processCLAUDE_CONFIG_DIRfrom each process's environmentAlways includes
~/.claude(default) plus anyCLAUDE_CONFIG_DIRset in abtop's own env as baseline.Changes
ClaudeCollectornow maintains aVec<ConfigDir>refreshed each tickfind_transcriptsearches across all discovered project directoriesrate_limit::read_rate_limitschecks all known config dirsread_env_var_from_proc()reads/proc/<pid>/environ(Linux-only, with non-Linux stub)Testing
cargo clippy -- -D warnings- cleancargo test- 31/31 passcargo build --release- compiles, binary functionalabtop --oncecorrectly shows all 4 active sessions/proc/<pid>/environreading verified on live system (68 env vars readable)Limitations
/procreading is Linux-only. On macOS, discovery falls back toCLAUDE_CONFIG_DIRenv var + default~/.claude(same as current behavior). A future enhancement could usesysctl kern.procargs2on macOS.abtop --setupto have been run in each config directory separately (each Claude instance needs its own statusline hook).