Skip to content

feat(provider): re-authenticate Claude from within T3 Code#4151

Open
sideeffffect wants to merge 3 commits into
pingdotgg:mainfrom
sideeffffect:feat/claude-reauth
Open

feat(provider): re-authenticate Claude from within T3 Code#4151
sideeffffect wants to merge 3 commits into
pingdotgg:mainfrom
sideeffffect:feat/claude-reauth

Conversation

@sideeffffect

@sideeffffect sideeffffect commented Jul 19, 2026

Copy link
Copy Markdown

Problem

When Claude Code's OAuth token expires, a turn fails with:

LLM error: Failed to authenticate. API Error: 401 OAuth access token has expired. Re-authenticate to continue.

Today the only way to recover is to leave T3 Code, open a shell, and run the
Claude login command by hand. There is no way to trigger and finish the
authentication flow from within the app.

What this does

Adds an in-app Re-authenticate action for Claude:

  • When a turn fails with an auth error, the thread error banner shows a
    Re-authenticate button.
  • When a provider reports unauthenticated, the provider status banner
    shows the same button (previously it only said "Sign in via the CLI to
    authenticate again." — a dead end). This generalizes to any provider that
    advertises a re-auth command.

Clicking it opens the thread's integrated terminal and runs
claude setup-token for that provider — using the instance's configured
binary and Claude HOME — so the interactive OAuth prompt (open URL, paste the
authorization code) is completed entirely inside T3 Code. No external shell.

How it works

  • contracts (packages/contracts/src/server.ts): new optional
    ServerProviderReauthentication descriptor (command / executable /
    args / label) on ServerProvider. Additive and back-compat — legacy
    producers omit it and consumers simply hide the action.
  • server (ClaudeProvider.ts, providerSnapshot.ts): the Claude provider
    advertises claude setup-token (resolved to the configured binaryPath) on
    its installed snapshots, threaded through buildServerProvider.
  • web (ProviderStatusBanner, ThreadErrorBanner, ChatView): render the
    action and run the command by reusing the existing project-script terminal
    launcher (open/reuse a terminal, focus it, write the command). A fresh
    terminal is preferred so the OAuth prompt does not collide with an in-flight
    shell.

claude setup-token was chosen because it is the supported interactive login
for the CLI/SDK model T3 Code already uses and produces a fresh long-lived
token.

Tests / checks

  • pnpm typecheck — clean.
  • pnpm lint — 0 errors, no new warnings.
  • pnpm fmt:check — clean.
  • New unit tests: contract round-trip/back-compat for the descriptor
    (server.test.ts) and the Claude snapshot exposing it
    (ProviderRegistry.test.ts). Touched suites pass (contracts 5/5, server
    provider registry 36/36, web ChatView logic 22/22).

Notes / scope

  • Scoped to server + contracts + web (the primary experience). Desktop shares
    the web UI; mobile is unaffected (it only reads auth.status).
  • Automatic detection of the expired-token state at probe time is not
    attempted here: Claude Code's local init still succeeds with cached
    credentials, so the reliable signal is the runtime 401, which is exactly
    where the thread-error-banner button appears. The status-banner button covers
    providers that do report unauthenticated.
  • Manual verification of the live terminal launch could not be run headless in
    this environment; the launch reuses the already-shipping project-script path.

Docs: docs/providers/claude.md gains a short "My Claude Login Expired"
section.


Note

Low Risk
Additive contract field and UI recovery path; no changes to turn execution or credential storage beyond launching the existing CLI login command with correct env.

Overview
Adds an optional ServerProviderReauthentication descriptor on provider snapshots so the client can run an interactive CLI login without leaving the app.

Claude advertises claude setup-token (respecting configured binary and CLAUDE_CONFIG_DIR for custom homes) on checked and pending snapshots; Path is wired through pending snapshot creation in the driver.

Web: ProviderStatusBanner and ThreadErrorBanner show a Re-authenticate button when the provider is unauthenticated or the thread error matches a narrow auth-expiry heuristic; ChatView launches the command via the existing project-script terminal path (new terminal, optional env), targeting the thread session’s provider instance rather than the composer selection.

Contract tests, registry tests, and docs/providers/claude.md document the recovery flow.

Reviewed by Cursor Bugbot for commit b11de81. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add in-app Claude re-authentication from the thread error and provider status banners

  • Adds a ServerProviderReauthentication schema to provider snapshots carrying the command, executable, args, label, and optional env needed to launch a login flow.
  • Claude provider snapshots now populate this descriptor (running claude setup-token) including CLAUDE_CONFIG_DIR when a custom home path is configured.
  • ChatViewContent detects auth-related thread errors and surfaces a "Re-authenticate" button that runs the login command in a new integrated terminal.
  • ProviderStatusBanner and ThreadErrorBanner each gain an optional onReauthenticate callback that renders a "Re-authenticate" button with a Key icon.
  • Adds a "My Claude Login Expired" section to claude.md explaining the in-app flow.

Macroscope summarized b11de81.

When Claude Code's OAuth token expires mid-turn ("Failed to authenticate.
API Error: 401 OAuth access token has expired. Re-authenticate to
continue.") the only way to recover was to leave T3 Code and run the login
command in an external shell. This adds an in-app re-authentication path.

- contracts: add an optional ServerProviderReauthentication descriptor on
  ServerProvider (command / executable / args / label). Additive and
  back-compat: legacy producers omit it and consumers hide the action.
- server: the Claude provider advertises "claude setup-token", resolved to
  the instance's configured binary, on its installed snapshots so custom
  binaries re-authenticate the same executable they run.
- web: the thread error banner (on auth-looking turn failures) and the
  provider status banner (when a provider reports "unauthenticated") offer a
  "Re-authenticate" action that runs the login command in the thread's
  integrated terminal, reusing the proven project-script launcher. The user
  completes the interactive OAuth prompt (open URL, paste code) in-app.

Docs (docs/providers/claude.md) and tests (contracts + provider snapshot)
included.
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d6b59e84-5bb5-42b0-b61a-2bd7b57e6a2b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 19, 2026
Comment thread apps/web/src/components/ChatView.tsx
Comment thread apps/web/src/components/ChatView.tsx
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment thread apps/web/src/components/ChatView.tsx
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new user-facing feature (in-app re-authentication for Claude) with new UI elements, terminal integration, and error detection heuristics. New features introducing user-facing behavior warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Resolves the Cursor Bugbot / Macroscope review findings on pingdotgg#4151:

- Propagate CLAUDE_CONFIG_DIR (High): the re-authentication descriptor now
  carries an optional `env` map, and the Claude provider fills it with the
  instance's resolved home (via resolveClaudeHomePath) when a custom home is
  configured. The web launcher layers it onto the terminal env, so
  `setup-token` refreshes the correct instance's credentials instead of the
  default config dir. Adds contract + provider tests.
- Pending snapshot exposes re-auth (Medium): makePendingClaudeProvider now
  attaches the descriptor, so a turn failing before the first status check
  still offers the recovery action.
- Target the failing instance (Medium): the thread error banner resolves the
  re-auth provider from the thread session's providerInstanceId (the one that
  produced lastError), not the composer's currently-selected provider.
- Tighten auth-error heuristic (Medium): isProviderAuthError now matches
  credential-specific phrasing instead of bare 401/403/oauth/api-key
  substrings that also appear in generic tool/HTTP failures.
- Shell-quote the command (Low): the login command line is POSIX-quoted so a
  configured binary path with spaces is not word-split when pasted.
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts Outdated

@cursor cursor Bot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c5276be. Configure here.

Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts Outdated
…s the POSIX single-quoting added in the previous commit: it broke && other shells the integrated terminal may use — cmd.exe treats single quotes && as literal (word-splitting a spaced path), and single quotes suppress ~ && expansion in bash/zsh. No single pre-joined string is correct across all of && them, so `command` is now a plain space-join optimized for the common && `claude`/PATH (and unquoted-path) case, with `executable`/`args` exposed && separately for callers needing exact argv.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant