Repository navigation
Scope usage per CLAUDE_CONFIG_DIR, includin authentication - #266
Conversation
…g token authentication
The usage cache (usage.json) and lock file (usage.lock) were shared
across all Claude Code profiles, causing session-usage, weekly-usage,
reset-timer, and weekly-reset-timer widgets to display data from the
wrong account when CLAUDE_CONFIG_DIR pointed to a non-default profile.
Replace the hardcoded file paths with per-profile paths using a
SHA-256 hash of the resolved CLAUDE_CONFIG_DIR, matching the existing
pattern used by getBlockCachePath() in jsonl-cache.ts.
Claude Code stores per-profile credentials in the macOS keychain using the service
name Claude Code-credentials-{sha256(configDir)[:8]}. For ~/.claude-boost, that's
Claude Code-credentials-ac4e02fa. The old code never looked up this specific entry —
it only tried the generic Claude Code-credentials service, then sorted all candidates by mtime.
4f7a07b to
ec28376
Compare
|
For reference, main has since picked up part of this. #573 now reads the |
|
I merged current main and narrowed this PR to per-profile usage cache and lock files. Main now handles credential selection, including profile isolation, username retries, and Keychain timeouts, so I preserved that implementation. Usage caches, request locks, and no-credentials backoff locks now use profile-specific filenames. Token fingerprints and existing backoff behavior are preserved. The old shared files are ignored and left untouched; each profile populates its own cache. Added tests covering two profiles sharing one home, independent caches and backoffs, lock cleanup, and legacy-file handling. |
Upstream: Extra Usage Limit widget (sirmalloc#756), live widget preview while picking (sirmalloc#755), Fast Mode widget (sirmalloc#754), transcript block fallback fixes (sirmalloc#752), editor keys on a global install (sirmalloc#751), git cache TTL (sirmalloc#750), npx cached copy skip (sirmalloc#749), Block Usage hide at 100% (sirmalloc#747), Block Reset Timer hide until 100% (sirmalloc#697), fish-style branch abbreviation (sirmalloc#614), jj detached HEAD (sirmalloc#705), hooks save warning (sirmalloc#703), dev reload (sirmalloc#700), merge ends at a hidden widget (sirmalloc#698), Block Forecast and Block Limit Timer widgets (sirmalloc#699), contributor guide (sirmalloc#706), POSIX path case fix (sirmalloc#707), whitespace-distinct conflict filenames (sirmalloc#709), Quick Start reorder (sirmalloc#715), bunx launch guidance (sirmalloc#714), jj diff summary counts (sirmalloc#711), powerline manual separators (sirmalloc#713), keychain credential by account (sirmalloc#532), Keychain probe timeout (sirmalloc#760), usage cache scoped per CLAUDE_CONFIG_DIR (sirmalloc#266), test isolation (sirmalloc#717, sirmalloc#753), dev-dependency bumps (sirmalloc#745) Conflicts resolved per the standard-resolution table; fork deletions re-applied. Hand edits outside conflicts: - src/utils/global-command-resolution.ts: fork-rename (ccstatusline@ -> ccstatusline-usage@ in upstream's new bunx pattern) - src/utils/__tests__/global-package-manager.test.ts: fork-rename (package dir ccstatusline-usage in upstream's new tests) - src/utils/usage-fetch.ts: compat fix - cacheUsageData gained a fetchedAtMs arg (upstream sirmalloc#266); adapted the fork-only fetchFreshUsageData call site - src/utils/__tests__/usage-fetch.test.ts: compat fixes - cache/lock now hashed per CLAUDE_CONFIG_DIR (usageFilePath helper) in four fork tests; upstream fableUsage renamed to fork's weeklyFableUsage; seedUsageCache takes TokenHome - src/utils/__tests__/usage-prefetch.test.ts: compat fix - mockFetchUsageData renamed to upstream's mockFetchUsage in cleanly-merged tests - README.md: took upstream's Quick Start move (sirmalloc#715) and dropped the fork's old copy; fork-rename of its ccstatusline@ specifiers; links to fork-deleted docs (docs/USAGE.md, docs/WINDOWS.md) replaced with the fork's inline text - CONTRIBUTING.md: links to the fork-deleted docs/DEVELOPMENT.md pointed at the README Development section - docs/test-retirements.md: ledger entries for the 12 upstream test renames (sirmalloc#697, sirmalloc#698, sirmalloc#700, sirmalloc#705, sirmalloc#713, sirmalloc#760)
The usage lock held every fetch off, whichever login made it. A 429 for one access token kept the usage widgets on cached numbers or "Rate limited" until its Retry-After ran out, often an hour, even after Claude Code refreshed the login: the new token got a 200 as soon as the lock file was deleted by hand. A lock written for the API refusing a request, with a 429 or a lasting answer such as a 401, now names the fingerprint of the access token the request was sent with, and a fetch with another token skips it. That covers both read paths: the known login's, which a token refresh leaves by changing the login's stamp, and the one that reads the credentials. The fingerprint is the access token's, since a refresh may keep the refresh token the cache's fingerprint comes from. A lock without one (the in-flight record, a failure of the server, the network or the response, a file from an older version) still holds every login off. Profiles used side by side share the lock file, so a request that replaces another token's active lock with its in-flight record puts that lock back once it succeeds, instead of ending the other login's backoff early. Upstream sirmalloc#266 now gives each profile its own lock file, so the part about profiles sharing one is moot; a token refresh within one profile still needs the per-token lock.
This pull request updates the usage tracking logic to support multiple configuration profiles by scoping the usage cache and lock files to the current config directory. It also improves the logic for retrieving API credentials, especially on macOS, by first checking for a config-directory-specific keychain entry. The test suite has been updated to reflect these changes and add coverage for the new fallback behavior.
The usage cache (usage.json) and lock file (usage.lock) were shared
across all Claude Code profiles, causing session-usage, weekly-usage,
reset-timer and weekly-reset-timer widgets to display data from the
wrong account when CLAUDE_CONFIG_DIR pointed to a non-default profile.
Replace the hardcoded file paths with per-profile paths using a
SHA-256 hash of the resolved CLAUDE_CONFIG_DIR, matching the existing
pattern used by getBlockCachePath() in jsonl-cache.ts.
Claude Code stores per-profile credentials in the macOS keychain using the service
name Claude Code-credentials-{sha256(configDir)[:8]}. For ~/.claude-boost, that's
Claude Code-credentials-ac4e02fa. The old code never looked up this specific entry —
it only tried the generic Claude Code-credentials service, then sorted all candidates by mtime.