feat(claude): support CLAUDE_CONFIG_DIRS for multiple data dirs (closes #208)#288
Merged
Conversation
Adds an OS-delimited list env var so a user with more than one Claude account or profile can scan all of them in a single run. Sessions across every configured dir merge into one ProjectSummary per project, matching the option-1 design agreed on the issue thread (no per-account splitting in the data model or the UI). Format: `CLAUDE_CONFIG_DIRS=~/.claude-work:~/.claude-personal` on POSIX, `;`-separated on Windows. Precedence is CLAUDE_CONFIG_DIRS > CLAUDE_CONFIG_DIR > ~/.claude. Empty entries in the list are skipped, duplicates are deduped on resolved path, and a missing or unreadable dir does not abort the scan of the others. If the user explicitly set CLAUDE_CONFIG_DIRS but every listed entry is unreadable, a one-line stderr hint identifies the attempted paths and the platform's expected delimiter, so a Windows user typing the POSIX `:` does not get a silent zero-row result. `~` is now also expanded in CLAUDE_CONFIG_DIR for consistency. Implementation is intentionally narrow: only `claude.ts` changes, plus a small parser-cache key update so a stale cache from one config does not bleed into a run with a different config (matters for the macOS menubar and GNOME extension which run as long-lived processes). The merge happens for free in `src/parser.ts:scanProjectDirs`, which keys ProjectSummary entries by canonical cwd (or the sanitized slug as a fallback). Two SessionSource entries with the same `project` field land under the same key and combine their sessions, regardless of which dir they came from. No new fields on SessionSource / SessionSummary / ProjectSummary, and no UI changes. Tests: 12 fixture-based cases covering the unset path (default ~/.claude), single-dir override via CLAUDE_CONFIG_DIR, multi-dir override via CLAUDE_CONFIG_DIRS, ~ expansion, dedup of repeated entries, leading/trailing/doubled delimiters, missing dir tolerated, file-not-directory entry tolerated, empty CLAUDE_CONFIG_DIRS falls back to single-dir env, and two parser-level integration tests asserting (a) two sessions from two dirs sharing one cwd produce one ProjectSummary with combined totals and no `account`/`accountPath` fields anywhere, and (b) two sessions sharing a slug but with different canonical cwds still merge by slug at the project-rollup layer (option 1 behavior pinned so a future refactor cannot quietly swap to cwd-aware merging without an explicit opt-in). Supersedes the alternative implementation in #227, which builds per-account attribution (option 2) instead.
This was referenced May 10, 2026
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.
Closes #208. Supersedes #227 (which built per-account attribution — option 2 — after the issue thread settled on option 1).
Summary
A user with more than one Claude account or profile (e.g.
~/.claude-workand~/.claude-personal) can setCLAUDE_CONFIG_DIRSto an OS-delimited list and codeburn scans all of them in one run. Sessions across every configured directory roll up into one row per project — option 1, total aggregation. No per-account split, noaccountfield on the data model, no UI changes.Precedence:
CLAUDE_CONFIG_DIRS>CLAUDE_CONFIG_DIR>~/.claude.Why this is small
The merge happens for free in
src/parser.ts:scanProjectDirs, which already keysProjectSummaryentries by canonical cwd (or sanitized slug as a fallback). TwoSessionSourceentries from different dirs with the sameprojectfield naturally collapse into one row. So almost the entire change is insrc/providers/claude.ts:discoverSessions, walking N dirs instead of one.Multi-agent review before push
This branch was attacked by three independent reviewers:
:case), parser cache key now includesCLAUDE_CONFIG_DIRSandCLAUDE_CONFIG_DIRso a long-lived menubar/GNOME process does not return stale data after a config change,~expansion inCLAUDE_CONFIG_DIRdocumented in CHANGELOG. The remaining HIGH/MEDIUM items are pre-existing parser behavior unrelated to this PR.Files changed
src/providers/claude.tssrc/parser.tsclearSessionCachetests/providers/claude-config-dirs.test.tsREADME.mdCHANGELOG.mdVerification
npm run buildclean.SessionSource/SessionSummary/ProjectSummary.~expansion documented as a behavior change in CHANGELOG.Test plan
CLAUDE_CONFIG_DIRS=~/.claude-work:~/.claude-personal codeburn report --format json --provider claude— confirm one row per project even when both dirs share a project.CLAUDE_CONFIG_DIRS=/does/not/exist codeburn— confirm one-line stderr hint, exit 0, no crash.codeburn(no env vars) behaves identically to current main.