Skip to content

Add Linux support for Claude Code OAuth token retrieval#258

Merged
AnnatarHe merged 1 commit intomainfrom
claude/add-anthropic-usage-statusline-23SCL
Mar 13, 2026
Merged

Add Linux support for Claude Code OAuth token retrieval#258
AnnatarHe merged 1 commit intomainfrom
claude/add-anthropic-usage-statusline-23SCL

Conversation

@AnnatarHe
Copy link
Copy Markdown
Contributor

@AnnatarHe AnnatarHe commented Mar 13, 2026

Summary

Extends OAuth token retrieval for Claude Code to support Linux systems in addition to macOS. Previously, rate limit quota information was only available on macOS via Keychain. This change adds support for Linux by reading credentials from ~/.claude/.credentials.json.

Key Changes

  • Refactored credential handling: Renamed keychainCredentials to claudeCodeCredentials and keychainOAuthEntry to claudeCodeOAuthEntry to reflect support for multiple credential sources
  • Platform-specific token retrieval: Updated fetchClaudeCodeOAuthToken() to dispatch to platform-specific implementations:
    • macOS: fetchOAuthTokenFromKeychain() (existing behavior via security command)
    • Linux: fetchOAuthTokenFromCredentialsFile() (new, reads from ~/.claude/.credentials.json)
  • Extracted common parsing logic: Created parseOAuthTokenFromJSON() to handle JSON parsing and validation for both platforms
  • Updated quota display: Modified formatStatuslineOutput() and outputFallback() in cc_statusline.go to show quota utilization on both macOS and Linux
  • Updated rate limit fetching: Modified fetchRateLimit() in cc_info_timer.go to support both platforms
  • Comprehensive test coverage: Added 6 new test cases covering:
    • Valid OAuth token parsing from JSON
    • Missing/empty OAuth tokens
    • Invalid JSON handling
    • File-based credential reading (valid, missing file, invalid JSON)

Implementation Details

  • Linux credentials are read from ~/.claude/.credentials.json with proper file permission handling (0600)
  • Both platforms use the same JSON structure for credentials (claudeAiOauth object with accessToken field)
  • Error messages are now platform-agnostic (e.g., "no OAuth access token found in credentials" instead of "in keychain")
  • Tests use temporary directories and environment variable mocking to avoid system dependencies

https://claude.ai/code/session_01VQbqeC4PtoWTXdvETzsepV


Open with Devin

Read OAuth token from ~/.claude/.credentials.json on Linux, in addition
to the existing macOS Keychain integration. Refactored token fetching
into platform-dispatched helpers with a shared JSON parser for reuse.

https://claude.ai/code/session_01VQbqeC4PtoWTXdvETzsepV
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Claude Code tool by introducing Linux support for OAuth token retrieval, which in turn enables the display of rate limit quota information on Linux systems. Previously, this feature was exclusive to macOS due to its reliance on Keychain access. The changes involve refactoring credential handling, implementing platform-specific token fetching mechanisms, and centralizing JSON parsing logic, thereby improving cross-platform compatibility and user experience for Claude Code users.

Highlights

  • Refactored Credential Handling: Renamed keychainCredentials to claudeCodeCredentials and keychainOAuthEntry to claudeCodeOAuthEntry to reflect support for multiple credential sources.
  • Platform-Specific Token Retrieval: Updated fetchClaudeCodeOAuthToken() to dispatch to platform-specific implementations: macOS via fetchOAuthTokenFromKeychain() and Linux via fetchOAuthTokenFromCredentialsFile() (new, reads from ~/.claude/.credentials.json).
  • Extracted Common Parsing Logic: Created parseOAuthTokenFromJSON() to handle JSON parsing and validation for both platforms.
  • Updated Quota Display: Modified formatStatuslineOutput() and outputFallback() in cc_statusline.go to show quota utilization on both macOS and Linux.
  • Updated Rate Limit Fetching: Modified fetchRateLimit() in cc_info_timer.go to support both platforms.
  • Comprehensive Test Coverage: Added 6 new test cases covering valid OAuth token parsing, missing/empty OAuth tokens, invalid JSON handling, and file-based credential reading.
Changelog
  • commands/cc_statusline.go
    • Expanded quota utilization display logic to include Linux.
    • Updated fallback output to show quota information on Linux.
  • commands/cc_statusline_test.go
    • Modified statusline output tests to assert quota display on Linux.
  • daemon/anthropic_ratelimit.go
    • Renamed credential structs from keychainCredentials to claudeCodeCredentials and keychainOAuthEntry to claudeCodeOAuthEntry.
    • Refactored fetchClaudeCodeOAuthToken to use a platform-specific switch for macOS and Linux.
    • Introduced fetchOAuthTokenFromKeychain for macOS-specific retrieval.
    • Added fetchOAuthTokenFromCredentialsFile for Linux-specific file-based retrieval from ~/.claude/.credentials.json.
    • Created parseOAuthTokenFromJSON to centralize JSON parsing logic for credentials.
    • Updated error messages to be platform-agnostic.
  • daemon/anthropic_ratelimit_test.go
    • Added imports for os and path/filepath for file system operations in tests.
    • Updated keychainCredentials type in existing tests to claudeCodeCredentials for consistency.
    • Introduced new test cases for parseOAuthTokenFromJSON covering valid, missing OAuth, empty token, and invalid JSON scenarios.
    • Added new test cases for fetchOAuthTokenFromCredentialsFile covering valid file, missing file, and invalid JSON scenarios, utilizing temporary directories and environment variable mocking.
  • daemon/cc_info_timer.go
    • Updated fetchRateLimit to include Linux in its supported operating systems for fetching Anthropic rate limit data.
Activity
  • No specific activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively extends OAuth token retrieval for Claude Code to support Linux systems. The refactoring of credential handling into platform-specific functions for macOS and Linux is well-executed, and extracting common JSON parsing logic into a shared function improves code reuse. The addition of comprehensive test cases for the new Linux functionality is commendable. I have one minor suggestion to use constants for file path components to enhance maintainability, aligning with best practices for path handling. Overall, this is a high-quality change.

Comment on lines +85 to +97
func fetchOAuthTokenFromCredentialsFile() (string, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("failed to get home directory: %w", err)
}

data, err := os.ReadFile(filepath.Join(homeDir, ".claude", ".credentials.json"))
if err != nil {
return "", fmt.Errorf("credentials file read failed: %w", err)
}

return parseOAuthTokenFromJSON(data)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To improve maintainability and avoid hardcoding file path components, consider defining ".claude" and ".credentials.json" as constants. This makes the path easier to read and manage, especially if these values are used elsewhere. This aligns with best practices for platform-independent path handling.

func fetchOAuthTokenFromCredentialsFile() (string, error) {
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("failed to get home directory: %w", err)
	}

	const (
		claudeConfigDir       = ".claude"
		claudeCredentialsFile = ".credentials.json"
	)
	credentialsPath := filepath.Join(homeDir, claudeConfigDir, claudeCredentialsFile)
	data, err := os.ReadFile(credentialsPath)
	if err != nil {
		return "", fmt.Errorf("credentials file read failed: %w", err)
	}

	return parseOAuthTokenFromJSON(data)
}
References
  1. For platform-independent paths, use filepath.Join to combine segments and os.UserHomeDir() to get the home directory, rather than hardcoding path separators or environment variables like $HOME. Defining path components as constants further enhances maintainability and readability.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment thread commands/cc_statusline.go
// Quota utilization (macOS only - requires Keychain for OAuth token)
if runtime.GOOS == "darwin" {
// Quota utilization (macOS: Keychain, Linux: ~/.claude/.credentials.json)
if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 CLAUDE.md rule states quota is macOS-only but code now enables it on Linux without updating the rule

CLAUDE.md line 127 states: "CC statusline quota display is macOS-only (requires Keychain access to Claude Code OAuth token)". The new code at commands/cc_statusline.go:218 adds || runtime.GOOS == "linux" to enable quota display on Linux, directly contradicting this documented constraint. The same violation applies to the fallback output at commands/cc_statusline.go:282 and the daemon fetch guard at daemon/cc_info_timer.go:398. CLAUDE.md must be updated to reflect that quota is now supported on both macOS (Keychain) and Linux (~/.claude/.credentials.json).

Prompt for agents
Update CLAUDE.md line 127 in the Important Notes section to reflect the new Linux support. Change:

- CC statusline quota display is macOS-only (requires Keychain access to Claude Code OAuth token)

To something like:

- CC statusline quota display is supported on macOS (Keychain) and Linux (~/.claude/.credentials.json) for Claude Code OAuth token access

Also update docs/CC_STATUSLINE.md in multiple places:
- Line 15: Remove "macOS only" or change to "macOS and Linux"
- Line 81: Update parenthetical about macOS only
- Line 87: Update the Platform Note section to reflect Linux now shows quota
- Lines 200-204: Update the Requirements for Quota Utilization section
- Line 245: Update the troubleshooting entry

Also update README.md line 100: Remove "macOS only" from the quota row description.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@AnnatarHe AnnatarHe merged commit 48679a8 into main Mar 13, 2026
6 checks passed
@AnnatarHe AnnatarHe deleted the claude/add-anthropic-usage-statusline-23SCL branch March 13, 2026 10:40
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 13, 2026

Codecov Report

❌ Patch coverage is 62.50000% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
daemon/anthropic_ratelimit.go 66.66% 6 Missing and 1 partial ⚠️
commands/cc_statusline.go 50.00% 1 Missing ⚠️
daemon/cc_info_timer.go 0.00% 0 Missing and 1 partial ⚠️
Flag Coverage Δ
unittests 39.89% <62.50%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
commands/cc_statusline.go 59.77% <50.00%> (+1.11%) ⬆️
daemon/cc_info_timer.go 77.56% <0.00%> (+4.48%) ⬆️
daemon/anthropic_ratelimit.go 34.00% <66.66%> (+34.00%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

2 participants