Repository navigation
fix(claude): show Refresh guidance after external login - #4402
Conversation
Detect credential-file and Keychain attribute changes after an unresolved OAuth absence without reading foreign Keychain payloads or relaxing prompt policy. Preserve Auto fallback and cancellation, and reuse explicit Refresh for access repair. Fixes #3395 Thanks @PoroGramr for the report.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: fix(claude): show Refresh guidance after external login This is item 1/1 in the current shard. Shard 0/1. This temporary status tracks the active review worker. The completed review will appear in the durable ClawSweeper review comment. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 791b385552
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| respectKeychainPromptCooldown: respectKeychainPromptCooldown, | ||
| allowClaudeKeychainRepairWithoutPrompt: allowClaudeKeychainRepairWithoutPrompt, | ||
| clearInvalidCache: clearInvalidCache) | ||
| if defaults?.object(forKey: failureKey) != nil { defaults?.removeObject(forKey: failureKey) } |
There was a problem hiding this comment.
Preserve the ambient failure timestamp for override tokens
When a saved OAuth-token account or a one-off CODEXBAR_CLAUDE_OAUTH_TOKEN is used, Repository.loadRecord returns an .environment record while the profile identifier still comes from the ambient credentials-file path, so this unconditional removal clears the default Claude Code profile's missing-credential baseline. If Claude Code logs in while that override is active and the user later switches back to the System account, the next inaccessible-keychain read is treated as the first failure and still says to run claude instead of reporting the already-new credential timestamp. Only clear this profile-scoped baseline after reading a credential belonging to that profile, or scope it separately by credential authority/account.
Useful? React with 👍 / 👎.
After an external Claude Code login, the default Only on user action policy correctly keeps credential reads behind explicit Refresh, but CodexBar can continue telling the user that credentials are missing. Detect newer credential metadata and replace that stale error with the change time and Refresh guidance in the menu and OAuth CLI output.
The probe requests only Keychain attributes with both no-UI controls enabled, plus fresh credentials-file modification times. It never requests the credential payload or grants access. Failure timestamps are scoped to the credential profile, survive restarts, and clear when credentials become readable. Custom profiles never use the global Keychain item. Auto still tries configured CLI/Web sources under their existing gates; successful fallback wins, failed fallback retains the actionable guidance, and cancellation stays terminal. The existing one-click menu Refresh action is reused.
Consolidate duplicate Keychain candidate/data readers and remove unreachable branches to keep production size down. Update
docs/claude.mdand the 0.73.1 Unreleased changelog. Thanks @PoroGramr for the report.Verification:
cd24c380e10with only the test query seam and regression fixture:source Scripts/test_environment.sh; swift test --build-system native --jobs 4 -Xswiftc -gnone --filter ClaudeExternalLoginFreshnessTests— 1 test failed with 3 assertions, displaying the original “Claude OAuth credentials not found” message.source Scripts/test_environment.sh; CODEXBAR_CLAUDE_RELOGIN_PROOF_DIR=/tmp/claude-relogin-26-proof swift test --build-system native --jobs 4 -Xswiftc -gnone --no-parallel --filter 'ClaudeExternalLogin|ClaudeOAuth|ClaudeSecurityCLI|ClaudeCLIBackgroundAvailability|KeychainNoUIQuery|ProviderArchitectureGatekeeper'— 429 tests in 49 suites passed. Includes fake attribute queries, consecutive file mtimes, unavailable metadata, profile isolation, policy gates, Auto fallback, cancellation, CLI JSON, and menu presentation../Scripts/test.sh --swift-command /tmp/claude-relogin-26-swift --direct-workers 4— 1,651/1,651 selections, 150/150 groups passed on the first attempt; 0 failures, retries, or timeouts. Verified direct mode, 4 workers, 14,491 discovered test methods. The wrapper forwardstest/buildto Swift with--build-system native --jobs 4 -Xswiftc -gnone.make check— passed; 0 violations.git diff --shortstat origin/main -- Sources WidgetExtension: 6 files changed, 127 insertions(+), 137 deletions(-), net −10. Tests: 2 files changed, 340 insertions(+).The prompt-free boundary is also supported by Apple's published implementation: attribute extraction passes null data outputs, and the auto-prompt/decryption branch requires itemData. The injected query test rejects data/reference requests and verifies both no-UI flags. No real-account probe, login flow, or app restart was used.
Synthetic renders of the production menu card, inspected before upload:
Fixes #3395