Skip to content

feat(claude): support CLAUDE_CONFIG_DIRS for multiple data dirs (closes #208)#288

Merged
iamtoruk merged 1 commit into
mainfrom
feat/claude-multi-dir
May 10, 2026
Merged

feat(claude): support CLAUDE_CONFIG_DIRS for multiple data dirs (closes #208)#288
iamtoruk merged 1 commit into
mainfrom
feat/claude-multi-dir

Conversation

@iamtoruk
Copy link
Copy Markdown
Member

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-work and ~/.claude-personal) can set CLAUDE_CONFIG_DIRS to 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, no account field on the data model, no UI changes.

# POSIX
CLAUDE_CONFIG_DIRS=~/.claude-work:~/.claude-personal codeburn

# Windows
$env:CLAUDE_CONFIG_DIRS = "$env:USERPROFILE\.claude-work;$env:USERPROFILE\.claude-personal"; codeburn

Precedence: CLAUDE_CONFIG_DIRS > CLAUDE_CONFIG_DIR > ~/.claude.

Why this is small

The merge happens for free in src/parser.ts:scanProjectDirs, which already keys ProjectSummary entries by canonical cwd (or sanitized slug as a fallback). Two SessionSource entries from different dirs with the same project field naturally collapse into one row. So almost the entire change is in src/providers/claude.ts:discoverSessions, walking N dirs instead of one.

Multi-agent review before push

This branch was attacked by three independent reviewers:

  • Devil's advocate review found 1 BLOCKING + 3 HIGH + 3 MEDIUM concerns. Addressed: stderr hint when every configured dir is unreadable (catches the Windows-mistyped-: case), parser cache key now includes CLAUDE_CONFIG_DIRS and CLAUDE_CONFIG_DIR so a long-lived menubar/GNOME process does not return stale data after a config change, ~ expansion in CLAUDE_CONFIG_DIR documented in CHANGELOG. The remaining HIGH/MEDIUM items are pre-existing parser behavior unrelated to this PR.
  • End-to-end live verification ran 11 scenarios (default ~/.claude, single-dir override, multi-dir merge, missing dir, dedup, delimiter edge cases, ~ expansion, precedence, empty env). 11/11 PASS.
  • Spec-compliance audit verified all 12 spec items from issue feat: allow multiple account tracking #208 against the actual code. All PASS.

Files changed

File Purpose
src/providers/claude.ts Multi-dir discovery + ~ expansion + stderr hint
src/parser.ts Cache key now env-aware + exported clearSessionCache
tests/providers/claude-config-dirs.test.ts 12 fixture-based tests
README.md Multi-dir docs in Provider Notes + env var table
CHANGELOG.md Unreleased entry

Verification

  • 45 test files, 601 tests passing locally (12 new, all pass).
  • npm run build clean.
  • All 11 end-to-end scenarios pass (verified by independent agent).
  • No fields added to SessionSource / SessionSummary / ProjectSummary.
  • No UI changes (CSV / JSON / dashboard untouched).
  • ~ 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.
  • Default codeburn (no env vars) behaves identically to current main.

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.
@iamtoruk iamtoruk merged commit b72e51e into main May 10, 2026
3 checks passed
@iamtoruk iamtoruk deleted the feat/claude-multi-dir branch May 10, 2026 05:04
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.

feat: allow multiple account tracking

1 participant