Skip to content

fix: live-probe macOS Keychain auth for Claude Code CLI onboarding (#1199)#1217

Merged
muddlebee merged 6 commits intoTracer-Cloud:mainfrom
devankitjuneja:fix/1199-macos-keychain-claude-code-onboarding
May 3, 2026
Merged

fix: live-probe macOS Keychain auth for Claude Code CLI onboarding (#1199)#1217
muddlebee merged 6 commits intoTracer-Cloud:mainfrom
devankitjuneja:fix/1199-macos-keychain-claude-code-onboarding

Conversation

@devankitjuneja
Copy link
Copy Markdown
Contributor

Fixes #1199

Describe the changes you have made in this PR

_classify_claude_code_auth() now accepts an optional binary_path. On macOS with no API key or credentials file, it runs a live claude -p ping to get a definitive auth result instead of returning None. Added 5 tests covering the new probe paths.

Demo/Screenshot

# Before
? Could not verify Anthropic Claude Code CLI login. What next?  ← dead end

# After
✓ Authenticated via macOS Keychain.  ← proceeds

Code Understanding and AI Usage

  • Yes, I used AI assistance
  • I have reviewed every single line of the AI-generated code
  • I can explain the purpose and logic of each function/component I added
  • I have tested edge cases and understand how the code handles them
  • I have modified the AI output to follow this project's coding standards and conventions

Explain your implementation approach:
Root cause and fix are documented in #1199.


Checklist

  • Proper PR title and linked issue
  • Self-review done
  • Can explain every function added
  • Tested thoroughly
  • Edge cases considered
  • Tests added
  • Follows project style

…racer-Cloud#1199)

On macOS, Claude Code stores OAuth credentials in Keychain rather than
~/.claude/.credentials.json. The auth classifier correctly returned None
(uncertain) for this case, but the onboarding wizard blocked on any
logged_in != True, leaving no path forward for Keychain-authenticated users.

Add _probe_keychain_auth() that runs `claude -p ping` with the full
inherited environment when on darwin with no API key or credentials file.
_classify_claude_code_auth() now accepts an optional binary_path; when
provided on macOS it delegates to the live probe, returning a definitive
True/False instead of None. _probe_binary() passes the resolved binary
through so the wizard gets a real auth result and proceeds without
requiring ANTHROPIC_API_KEY or a credentials file on disk.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 2, 2026

Greptile Summary

Replaces the previous heuristic auth detection (env var → credentials file → macOS Keychain guess) with a proper claude auth status subprocess probe in _probe_cli_auth, resolving the macOS Keychain dead-end. Error semantics are now correct throughout — None for indeterminate state, False only when the CLI explicitly reports unauthenticated — and the no-binary fallback path retains the original resolution order with ANTHROPIC_API_KEY checked first.

Confidence Score: 5/5

Safe to merge; all findings are P2 style/consistency nits.

No P0 or P1 issues found. The two P2 findings are stale claude login references in auth_hint and the module docstring — they don't affect runtime behavior. Logic, error handling, and test coverage are all correct.

No files require special attention beyond the two minor stale-string nits in claude_code.py.

Important Files Changed

Filename Overview
app/integrations/llm_cli/claude_code.py Refactors auth detection to use claude auth status (local, no API call) via new _probe_cli_auth; correct error semantics (None vs False); two minor stale references to the old claude login command remain (auth_hint field, module docstring).
tests/integrations/llm_cli/test_claude_code_adapter.py Adds 7 new tests covering probe paths (subscription, API key, not-logged-in, non-zero exit, timeout, OSError, non-JSON exit-0), plus a regression test ensuring API key isn't blocked by an unreadable credentials file; existing tests updated for the new two-call subprocess pattern.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[detect] --> B[_resolve_binary]
    B -->|no binary| C[CLIProbe installed=False]
    B -->|binary found| D[_probe_binary]
    D --> E[claude --version]
    E -->|error / non-zero| F[CLIProbe installed=False]
    E -->|exit 0| G[_classify_claude_code_auth binary_path]
    G -->|binary_path set| H[_probe_cli_auth]
    G -->|no binary_path + API key| I[True: ANTHROPIC_API_KEY]
    G -->|no binary_path + creds file| J[True: credentials.json]
    G -->|no binary_path + macOS| K[None: Keychain unclear]
    G -->|no binary_path + Linux/Win| L[False: not authenticated]
    H --> M[claude auth status]
    M -->|TimeoutExpired / OSError| N[None: probe failed]
    M -->|non-zero exit| O[None: command failed]
    M -->|exit 0 + JSON loggedIn=false| P[False: not authenticated]
    M -->|exit 0 + JSON loggedIn=true| Q[True: subscription or API key]
    M -->|exit 0 + non-JSON| R[True: Claude CLI legacy]
Loading

Reviews (4): Last reviewed commit: "fix: return None for timeout and OSError..." | Re-trigger Greptile

Comment thread app/integrations/llm_cli/claude_code.py
Comment thread app/integrations/llm_cli/claude_code.py Outdated
Ankit Juneja added 3 commits May 2, 2026 20:12
Replace live API ping with `claude auth status` (local, no billed tokens).
Parse JSON output to get definitive loggedIn state with email in detail.
Fall back to exit-code-only check for older CLI versions.
Fix ruff import sort in test file.
…obe_cli_auth

_classify_claude_code_auth now calls _probe_cli_auth (claude auth status) as
the primary source of truth when a binary is available on any platform.
Subscription login takes priority; ANTHROPIC_API_KEY is a fallback only when
no binary exists. Detail message reflects actual auth method from CLI JSON output.
@devankitjuneja
Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread app/integrations/llm_cli/claude_code.py Outdated
Comment thread app/integrations/llm_cli/claude_code.py Outdated
@devankitjuneja
Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread app/integrations/llm_cli/claude_code.py Outdated
@devankitjuneja
Copy link
Copy Markdown
Contributor Author

@greptileai review

@muddlebee muddlebee merged commit 5fd09ed into Tracer-Cloud:main May 3, 2026
10 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

🌊 Merged. @devankitjuneja is now permanently woven into git history. No take-backs. 😄


👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome.

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.

[BUG] Onboarding blocks Claude Code CLI setup on macOS when credentials are stored in Keychain

2 participants