Skip to content

fix(claude): show Refresh guidance after external login - #4402

Merged
steipete merged 2 commits into
mainfrom
triage/20260921-claude-relogin-26
Oct 10, 2026
Merged

steipete merged 2 commits into
mainfrom
triage/20260921-claude-relogin-26

Conversation

@steipete

Copy link
Copy Markdown
Owner

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.md and the 0.73.1 Unreleased changelog. Thanks @PoroGramr for the report.

Verification:

  • Red on cd24c380e10 with 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.
  • Green: 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 forwards test/build to Swift with --build-system native --jobs 4 -Xswiftc -gnone.
  • make check — passed; 0 violations.
  • Independent Codex review — no actionable P0–P2 findings.
  • 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:

Before After
Missing-credential guidance before the fix Credential-change timing and explicit Refresh guidance

Fixes #3395

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.
@clawsweeper

clawsweeper Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T03:14:58.377153Z 791b385 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@clawsweeper

clawsweeper Bot commented Oct 10, 2026

Copy link
Copy Markdown

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@steipete
steipete merged commit 44702dc into main Oct 10, 2026
10 checks passed
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.

Claude remains on “OAuth credentials not found” after external login until manual refresh

1 participant