Skip to content

fix: auto-discover sessions from multiple CLAUDE_CONFIG_DIR paths#36

Open
tbouquet wants to merge 3 commits intograykode:mainfrom
tbouquet:fix/multi-config-dir
Open

fix: auto-discover sessions from multiple CLAUDE_CONFIG_DIR paths#36
tbouquet wants to merge 3 commits intograykode:mainfrom
tbouquet:fix/multi-config-dir

Conversation

@tbouquet
Copy link
Copy Markdown
Contributor

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. ~/.claude for personal, ~/.claude-pro for enterprise via CLAUDE_CONFIG_DIR aliases) only see sessions from whichever single directory abtop happens to resolve at startup. The current CLAUDE_CONFIG_DIR support (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_DIR from abtop's own environment, discover it dynamically from each running Claude process:

  1. On each tick, read /proc/<pid>/environ for every detected Claude process
  2. Extract CLAUDE_CONFIG_DIR from each process's environment
  3. Scan sessions, transcripts, and rate limit files from all unique config directories

Always includes ~/.claude (default) plus any CLAUDE_CONFIG_DIR set in abtop's own env as baseline.

Changes

  • ClaudeCollector now maintains a Vec<ConfigDir> refreshed each tick
  • find_transcript searches across all discovered project directories
  • rate_limit::read_rate_limits checks all known config dirs
  • New read_env_var_from_proc() reads /proc/<pid>/environ (Linux-only, with non-Linux stub)

Testing

  • cargo clippy -- -D warnings - clean
  • cargo test - 31/31 pass
  • cargo build --release - compiles, binary functional
  • Runtime: abtop --once correctly shows all 4 active sessions
  • /proc/<pid>/environ reading verified on live system (68 env vars readable)

Limitations

  • /proc reading is Linux-only. On macOS, discovery falls back to CLAUDE_CONFIG_DIR env var + default ~/.claude (same as current behavior). A future enhancement could use sysctl kern.procargs2 on macOS.
  • Rate limits require abtop --setup to have been run in each config directory separately (each Claude instance needs its own statusline hook).

tbouquet and others added 3 commits April 17, 2026 22:51
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.
Copy link
Copy Markdown
Owner

@graykode graykode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 picks config_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_dirs to the slow poll tick would be consistent with how git stats / ports are handled.
  • A small unit test for read_env_var_from_proc covering 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Does not detect claude instances if claude's directory is a custom path

2 participants