Skip to content

Fix Claude source mode fallback on successful CLI login (#2403) - #2414

Open
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:fix/claude-connection-loss-2403
Open

Fix Claude source mode fallback on successful CLI login (#2403)#2414
Yuxin-Qiao wants to merge 4 commits into
steipete:mainfrom
Yuxin-Qiao:fix/claude-connection-loss-2403

Conversation

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor

Summary

Fixes #2403. When users logged into Claude via "Sign in with Claude Code..." (terminal CLI authentication), if claudeUsageDataSource was previously set to .web (or defaulted to .web), CodexBar would immediately attempt to fetch usage using unauthenticated browser cookies on the subsequent refresh. This resulted in an immediate 401 Unauthorized error ("Sign in to claude.ai...") and reverted the Claude status item to disconnected immediately after a "successful" login.

This PR updates runClaudeLoginFlow() so that a successful terminal CLI login automatically updates claudeUsageDataSource from .web to .auto, ensuring newly generated OAuth/CLI credentials are used immediately during refresh.

Changes Made

  1. Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:
    • Auto-update claudeUsageDataSource from .web to .auto when runClaudeLoginFlow completes with .success.
  2. Tests/CodexBarTests/ClaudeIssue2403ReproductionTests.swift:
    • Added unit tests reproducing web refresh disconnect after login, stale token account overrides, and OAuth unauthorized error prompts.
  3. Tests/CodexBarTests/ClaudeLoginFlowPolicyTests.swift:
    • Updated source assertion for .web source mode switching to .auto upon successful CLI login.

Verification Run

  • swift test --filter ClaudeLoginFlowTests
  • swift test --filter ClaudeIssue2403ReproductionTests
  • swiftformat Sources Tests

@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: d1dc6bd8e5

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let metadata = self.store.metadata(for: .claude)
self.settings.setProviderEnabled(provider: .claude, metadata: metadata, enabled: true)
if self.settings.claudeUsageDataSource == .web {
self.settings.claudeUsageDataSource = .auto

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 Avoid relabeling selected web accounts after CLI login

When a saved Claude token account contains a web/session cookie, this assignment changes an explicit web configuration to auto but leaves that token account selected. On the next app refresh, auto mode can pick the newly logged-in Claude Code OAuth/CLI credential before the selected account’s web cookie, while refresh publication still treats the selected token account as current and labels/caches that ambient snapshot under the saved account. In that configuration, users can see the CLI account’s usage under the selected web account; either clear/switch the selected token account or avoid auto-switching while a selected web-cookie account owns the refresh.

Useful? React with 👍 / 👎.

@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: 9471a060c9

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let metadata = self.store.metadata(for: .claude)
self.settings.setProviderEnabled(provider: .claude, metadata: metadata, enabled: true)
if self.settings.claudeUsageDataSource == .web {
self.settings.claudeUsageDataSource = .auto

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 Avoid routing web-mode logins to Admin API

When a user had explicitly selected Web but also has a Claude Admin API key saved or in the environment, this switch to Auto means the refresh triggered after a successful Claude Code login no longer uses the credential they just logged in with: ClaudeProviderDescriptor.resolveStrategies returns the admin API strategy immediately for Auto + admin key before reaching the OAuth/CLI planner. In that configuration the menu shows Admin API spend instead of the Claude Code account the login flow just authenticated; consider switching to a Claude Code-specific source or suppressing the admin-key auto shortcut for this post-login migration.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 30, 2026
@clawsweeper

clawsweeper Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 30, 2026, 10:42 PM ET / July 31, 2026, 02:42 UTC.

ClawSweeper review

What this changes

This PR changes successful Claude Code CLI login from preserving the selected Web usage source to selecting OAuth, updates the related login-flow expectation, and adds retries around existing Swift toolchain installation in CI.

Merge readiness

Blocked until real behavior proof is added - 10 items remain

Keep this PR open for repair and proof. Its current diff removes the successful-login step that enables Claude, so disabled or onboarding users can receive a success result while Claude remains unavailable; it also forces strict OAuth in a configuration where the existing CLI fallback may be required. The linked issue remains the canonical report, and this PR is its candidate fix.

Priority: P1
Reviewed head: 0a152d903715379dbc953806292b3d19211f7331

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The proposed fix addresses a real symptom but currently contains a high-impact login regression and lacks real behavior proof.
Proof confidence 🧂 unranked krab (1/6) Needs real behavior proof before merge: The PR body lists tests and formatting but has no redacted after-fix proof of a real Claude Code login followed by a persisted successful Claude refresh; add a terminal or app capture without tokens, account data, IP addresses, or private endpoints, then update the PR body for re-review.
Patch quality 🦪 silver shellfish (2/6) 2 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The PR body lists tests and formatting but has no redacted after-fix proof of a real Claude Code login followed by a persisted successful Claude refresh; add a terminal or app capture without tokens, account data, IP addresses, or private endpoints, then update the PR body for re-review.
Evidence reviewed 5 items Enablement regression in the PR diff: The branch replaces the unconditional Claude enablement call with a source-setting assignment. Source selection alone does not set the persisted provider-enabled state, so the common disabled-provider login path can report success without restoring Claude to the menu or refresh cycle.
Credential fallback regression: The branch changes Web to strict OAuth. The reviewed provider strategy behavior allows CLI fallback only for automatic selection, so no-Keychain or no-prompt OAuth policy can turn a successful external Claude CLI login into an immediate failed refresh.
Review continuity: The prior review on the current repair cycle already identified the missing enablement call, and the current head still removes it; this is a continuing blocker rather than a new late finding.
Findings 2 actionable findings [P1] Restore Claude enablement after successful login
[P2] Retain a CLI fallback when OAuth reads are unavailable
Security None None.

How this fits together

CodexBar’s Claude login flow runs Claude Code authentication, records the provider’s usage-source setting, and triggers the refresh that supplies the menu-bar usage state. That setting determines which stored credential strategy is eligible after login, so it must remain consistent with provider enablement and available credential access.

flowchart LR
    A[User starts Claude Code sign-in] --> B[Claude login flow]
    B --> C[Provider enablement and source policy]
    C --> D[Credential strategy selection]
    D --> E[Claude usage refresh]
    E --> F[Menu bar usage state]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The PR body lists tests and formatting but has no redacted after-fix proof of a real Claude Code login followed by a persisted successful Claude refresh; add a terminal or app capture without tokens, account data, IP addresses, or private endpoints, then update the PR body for re-review.
  • Restore Claude enablement after successful login (P1) - The patch removes the unconditional setProviderEnabled(..., enabled: true) call and only changes the usage source. A disabled provider—the normal onboarding state and the existing test setup—therefore remains disabled after a successful sign-in, so Claude stays hidden and does not refresh. Re-enable it independently of the source selection.
  • Retain a CLI fallback when OAuth reads are unavailable (P2) - This switches a successful external Claude CLI login into strict .oauth mode. With Keychain reads or OAuth prompting disabled, the OAuth strategy cannot read the newly created credential and the prior automatic CLI fallback is no longer eligible, so the next refresh fails immediately. Preserve a CLI-capable path for that policy combination.
  • Resolve merge risk (P1) - Existing users whose Claude provider is disabled can complete sign-in yet continue seeing Claude as disconnected or absent.
  • Resolve merge risk (P2) - Users who intentionally disable Keychain reads or OAuth prompting may lose the CLI fallback immediately after a successful CLI login.
  • Resolve merge risk (P1) - No redacted real-run evidence demonstrates the repaired post-login refresh across the persisted Web, disabled-provider, and restricted-Keychain cases.
  • Complete next step (P2) - The code defects are concrete, but the external contributor must also provide real after-fix behavior proof before merge; this is not a safe autonomous repair or automerge lane.
  • Improve patch quality - Restore provider enablement and cover the disabled-provider login path.
  • Improve patch quality - Preserve and test the restricted-Keychain CLI fallback path.
  • Improve patch quality - Add redacted after-fix terminal or app proof, then update the PR body; if no automatic review appears, ask a maintainer to comment @clawsweeper re-review.

Findings

  • [P1] Restore Claude enablement after successful login — Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35-37
  • [P2] Retain a CLI fallback when OAuth reads are unavailable — Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35-37
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Files affected 3 files; 21 additions, 4 deletions The functional login repair is small, but the branch also changes CI installation behavior outside the stated Claude login scope.
Workflow scope 2 CI install blocks retried Both Swift toolchain-install locations gain retry logic, so reviewers should assess the unrelated automation behavior independently.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #2403
Summary: This PR explicitly targets the Claude post-login disconnect described by the linked canonical issue, but its current patch does not safely resolve that behavior.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Repair the login policy before merge (recommended)
    Restore Claude enablement after success and retain a valid CLI fallback whenever OAuth credentials are unavailable under the user’s configured Keychain policy.
  2. Adopt strict OAuth intentionally
    Accept that successful Claude CLI sign-in can fail to refresh in restricted-Keychain configurations, with explicit maintainer approval and documented upgrade behavior.
  3. Pause this branch
    Pause the PR if the intended permanent relationship between successful CLI login, OAuth selection, and restricted credential access remains undecided.

Technical review

Best possible solution:

Keep provider enablement independent of source migration, preserve a CLI-capable refresh path when OAuth credentials cannot be read, cover those policy combinations with focused tests, and add redacted live proof of login followed by a persisted successful refresh.

Do we have a high-confidence way to reproduce the issue?

Yes, from source inspection: start a successful Claude login while the provider is disabled, then observe that the changed branch updates only the source setting and leaves the provider-disabled state intact. The restricted-Keychain path is likewise source-reproducible because strict OAuth no longer retains the existing automatic CLI fallback.

Is this the best way to solve the issue?

No. Switching away from a stale Web source addresses the reported symptom, but the current patch also drops required provider enablement and makes OAuth mandatory even when the successful CLI credential is the only usable path.

Full review comments:

  • [P1] Restore Claude enablement after successful login — Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35-37
    The patch removes the unconditional setProviderEnabled(..., enabled: true) call and only changes the usage source. A disabled provider—the normal onboarding state and the existing test setup—therefore remains disabled after a successful sign-in, so Claude stays hidden and does not refresh. Re-enable it independently of the source selection.
    Confidence: 0.99
  • [P2] Retain a CLI fallback when OAuth reads are unavailable — Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35-37
    This switches a successful external Claude CLI login into strict .oauth mode. With Keychain reads or OAuth prompting disabled, the OAuth strategy cannot read the newly created credential and the prior automatic CLI fallback is no longer eligible, so the next refresh fails immediately. Preserve a CLI-capable path for that policy combination.
    Confidence: 0.91

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8ef86077e70a.

Labels

Label justifications:

  • P1: The proposed code can make a normal successful Claude sign-in leave the provider disabled and unavailable to users.
  • merge-risk: 🚨 compatibility: The PR changes persisted Web-source behavior after login and can alter established provider availability and refresh behavior.
  • merge-risk: 🚨 auth-provider: The PR changes the credential source selected for the first post-login Claude refresh and may remove an existing CLI fallback.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body lists tests and formatting but has no redacted after-fix proof of a real Claude Code login followed by a persisted successful Claude refresh; add a terminal or app capture without tokens, account data, IP addresses, or private endpoints, then update the PR body for re-review.

Evidence

What I checked:

  • Enablement regression in the PR diff: The branch replaces the unconditional Claude enablement call with a source-setting assignment. Source selection alone does not set the persisted provider-enabled state, so the common disabled-provider login path can report success without restoring Claude to the menu or refresh cycle. (Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35, 0a152d903715)
  • Credential fallback regression: The branch changes Web to strict OAuth. The reviewed provider strategy behavior allows CLI fallback only for automatic selection, so no-Keychain or no-prompt OAuth policy can turn a successful external Claude CLI login into an immediate failed refresh. (Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35, 0a152d903715)
  • Review continuity: The prior review on the current repair cycle already identified the missing enablement call, and the current head still removes it; this is a continuing blocker rather than a new late finding. (Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift:35, 0a152d903715)
  • Proof remains absent: The PR body reports focused tests and formatting but provides no redacted after-fix run showing Claude Code login followed by a successful persisted Claude refresh.
  • Unrelated workflow scope: The PR modifies two CI Swift-install blocks in addition to the Claude bug fix, although the stated purpose is a Claude login regression; the CI retry change has no accompanying runtime proof or rationale in the PR body. (.github/workflows/ci.yml:291, 0a152d903715)

Likely related people:

  • steipete: Repository ownership is the only defensible routing signal available here; the decision concerns persisted Claude credential-source policy and the current-main login flow. (role: likely follow-up owner; confidence: low; files: Sources/CodexBar/Providers/Claude/ClaudeLoginFlow.swift)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (2 earlier review cycles)
  • reviewed 2026-07-30T11:29:56.796Z sha a115ccf :: needs real behavior proof before merge. :: [P1] Select the Claude Code OAuth source after login
  • reviewed 2026-07-30T15:21:19.417Z sha 60e9173 :: needs real behavior proof before merge. :: none

@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@Yuxin-Qiao
Yuxin-Qiao force-pushed the fix/claude-connection-loss-2403 branch from 60e9173 to 987f6d6 Compare July 30, 2026 15:24

@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: 987f6d696d

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +35 to +36
if self.settings.claudeUsageDataSource == .web {
self.settings.claudeUsageDataSource = .oauth

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep enabling Claude after a successful login

When Claude is disabled—the setup used by both login-flow tests and a normal sign-in onboarding path—replacing the unconditional setProviderEnabled(..., enabled: true) call with this source-only update leaves ProviderConfig.enabled false. Changing claudeUsageDataSource does not alter enablement, so the flow reports success and posts a notification while Claude remains hidden and is not refreshed; the new isProviderEnabledCached assertions consequently fail. Restore provider enablement independently of the selected source.

Useful? React with 👍 / 👎.

Comment on lines +73 to +74
#expect(actions.contains {
$0.0 == "Re-login at claude.ai" && $0.1 == .loginToProvider(url: "https://claude.ai/")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop expecting a web re-login action after switching to OAuth

After the successful flow changes this test's source from .web to .oauth, shouldOpenBrowserForWebSessionError rejects the source because it only accepts .auto or .web. Injecting a web unauthorized error therefore cannot produce the asserted “Re-login at claude.ai” action, so this test will fail once the earlier enablement assertion is repaired and does not validate the new routing behavior; assert the OAuth behavior or verify that the obsolete web action is absent instead.

Useful? React with 👍 / 👎.

@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: eaf2a3ef70

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let metadata = self.store.metadata(for: .claude)
self.settings.setProviderEnabled(provider: .claude, metadata: metadata, enabled: true)
if self.settings.claudeUsageDataSource == .web {
self.settings.claudeUsageDataSource = .oauth

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 a CLI fallback when OAuth reads are disabled

When “Disable Keychain access” or the no-prompt OAuth policy is enabled, claude auth login --claudeai can still succeed because it runs as an external CLI process, but this assignment then forces the provider into strict OAuth mode. ClaudeOAuthFetchStrategy cannot obtain the newly stored Keychain credential in that configuration, and its shouldFallback implementation only permits the working CLI strategy in .auto mode, so the refresh immediately fails despite the successful login. Keep a CLI fallback for this case rather than unconditionally selecting .oauth.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CodexBar cannot maintain connection with Claude anymore

1 participant