Skip to content

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

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

feat(provider): re-authenticate Claude from within T3 Code#4151
sideeffffect wants to merge 5 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

Medium Risk
Touches credential recovery and runs CLI login commands in the integrated terminal, but changes are additive, instance-scoped, and gated by heuristics and provider descriptors rather than altering core auth enforcement.

Overview
Introduces an optional ServerProviderReauthentication descriptor on provider snapshots so clients can launch a provider-specific login command in the integrated terminal.

Claude now advertises claude setup-token (respecting configured binary and CLAUDE_CONFIG_DIR for custom homes) on installed and pending snapshots, but not when the CLI is missing. ChatView wires Re-authenticate on the provider status banner (unauthenticated) and thread error banner (narrow auth-error heuristic), targeting the thread session’s provider instance and reusing the project-script terminal launcher with optional env overrides.

Contracts, snapshot building, UI banners, and docs/tests are updated for back-compat and the new flow.

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

Note

Add in-app Claude re-authentication via claude setup-token in the integrated terminal

  • Adds a ServerProviderReauthentication schema to the contracts layer, carrying the command, executable, args, label, and optional env needed to re-authenticate a provider.
  • checkClaudeProviderStatus and makePendingClaudeProvider now include a reauthentication descriptor in all Claude provider snapshots except when the CLI binary is missing.
  • The ProviderStatusBanner renders a

Macroscope summarized 530ad24.

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: 97db6a16-6b4e-4b96-a401-9620d55cf7df

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 adds a new user-facing feature: in-app re-authentication for Claude providers via new UI buttons, contract types, and terminal integration. New features introducing new workflows and user-facing behavior warrant human review to ensure the implementation meets design expectations.

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
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.
# Conflicts:
#	apps/server/src/provider/Layers/ClaudeProvider.ts

@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 464b68d. Configure here.

Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts
…es && Addresses a Bugbot finding: checkClaudeProviderStatus omitted the && reauthentication descriptor on its installed error/timeout snapshots && (version-probe timeout, non-zero exit, and the installed branch of a && version-probe failure), so the in-app Re-authenticate action was hidden in && exactly the recoverable states where an expired credential is a likely && cause. Attach reauthentication to those installed:true snapshots; the && missing-binary case still omits it (a CLI that isn't installed can't be && re-authenticated). Extends the two existing error-path tests.
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