fix(mobile): configure another Claude account from Providers#28928

merged2
main
GitHub fork: issue-watch/28872
opened9d agobySshivam
View on GitHubTwo-way sync enabledPR last imported 6d ago

Refs https://github.com/pingdotgg/t3code/issues/28872

Mobile Settings → Providers omitted Claude, so users could not register another already signed-in Claude config folder from their phone. It now lists Claude instances and lets users add, edit, or remove them through the existing environment-scoped server command and permissions. Sign in with the Claude CLI on the server first. The existing model picker can then select that instance; this does not add a login flow or change handoffs.

The rebase preserves both reviewed patches unchanged. Current JavaScript and isolated Linux server use head 351b8d356635eb6c48f0ba4a4fda17790d42579d, based on 8b44f42b14c8e273156474a924ccf29680dd7857. Compatibility with current main a07be97ab0753b2b5b0caecebba69d7f872594fa was rechecked on the combined merge tree below. The published PR head and its account runtime files are unchanged.

Verification at this head:

  • check:changed passed format, lint, knip, 40 package typechecks, 15 tests in five files, and five React compiler files. CI output.
  • Android Pixel 9 emulator, API 35, native fingerprint aba84043a4edb30381916d38ad6a4e7aad2cc74f: add, edit, confirm removal, select Claude B · Opus 5.5, save and reopen.
  • iPhone 17 Pro simulator, iOS 27, native fingerprint 994fd7249d9b61e4302f1767d4e23664fbde5277: add with an ID collision, edit, confirm removal, select Claude B · Opus 5.5, save and reopen.
  • Web: the existing Add provider wizard derives a free ID and saves the instance through the extracted shared helper. Both mobile clients receive it.

Native clients came from the validated fingerprint-matched cache on shiv, run r_i4r2wdypjpyx9q00. Their original cached build commits are unknown. Before images show the original Providers screen from the earlier verification; after images and recordings below use the head above. Recordings play at 2x speed.

Android before: no Claude setup controls.

Android after: the mobile-added instance and its config folder appear.

Android: add, edit, and confirm removal. The final removal was also checked in persisted settings and the live screen. Android settings

Android: select Claude B · Opus, save, and reopen to confirm selection. Android picker

iOS before: no Claude setup controls.

iOS after: add another entry despite an ID collision, then edit its name.

iOS add, edit and removal

The removed entry disappears after the server refreshes its provider catalog.

iOS: select Claude B · Opus, save, and reopen to confirm selection. iOS picker

The config folders contain test data. A local, no-network Claude protocol fixture reports an authenticated test identity for A. The web wizard registered B with the same fixture for picker verification. Mobile-created entries exercise the real save, edit, and removal paths; no credentials or paid turns were used.

Not shown: real Claude authentication or continuation after a weekly limit. This PR addresses registering an existing login folder from mobile. Windows registration and saved mobile selection were subsequently verified below.

Implemented with Claude Opus 5.5 / Claude Code; tested and reviewed with GPT-6.1 Sol / Codex.

Additional evidence for head 351b8d356635eb6c48f0ba4a4fda17790d42579d:

Main 9e85538535c8553901351112ab02dd1dd62db5ee, Android Pixel 9 / API 35 against an isolated Linux server at that revision: open Settings → Providers and look for a way to register another Claude folder. Claude and its registration controls are absent.

Main Providers flow

PR head, same device and Linux environment: open Providers, add Claude B with its config folder, and see the saved row. The recording plays at 2x speed without cuts.

Head Providers flow

Windows pass: native ARM64 Windows 11 VM t3-windows, OS 10.0.26200, Node v26.12.1. Server bundle built from head 351b8d356635eb6c48f0ba4a4fda17790d42579d with vp run build:bundle; runtime dependencies staged with the repository's CLI archive helpers and installed with vp install --prod. dist/bin.mjs SHA-256 is d8e5977ddea874bc11f3ff325266644d6d6a4606790f1417db3d7e95fb2d72a7. Android connects through an SSH forward to that server's loopback listener and uses the same native fingerprint recorded above.

Register C:/tmp/t3code-28872/account-b from Android on the Windows environment. The server re-probes it and the row reports Signed in.

Windows registration

Choose Claude B Windows · Opus 5.5, save, and reopen the picker. This recording plays at 2x speed without cuts.

Windows saved selection

After relaunching the native app, reopen the same thread's picker: Claude B Windows · Opus 5.5 remains selected. Save retains the mobile composer draft; it applies to the server thread when a turn starts. No turn was sent.

Windows selection after app relaunch

The Windows settings audit passed:

text
1head: 351b8d356635eb6c48f0ba4a4fda17790d42579d
2server: t3-windows / win32 / arm64 / Node v26.12.1
3instance: claudeAgent_claude_b_windows
4name: Claude B Windows
5driver: claudeAgent
6enabled: true
7config.homePath: C:/tmp/t3code-28872/account-b
8assertion: mobile registration persisted in native Windows server settings

Both Windows accounts use a local no-network protocol fixture. It reports synthetic authentication, answers initialization and usage probes, and sends no API requests. Real Claude authentication, quota recovery, and context handoff remain unverified.

Base compatibility recheck:

  • PR head 351b8d356635eb6c48f0ba4a4fda17790d42579d, current main a07be97ab0753b2b5b0caecebba69d7f872594fa. Their merge is conflict-free.
  • The overlapping base edit changes client-runtime's typecheck command to effect-tsgo tsrs --noEmit. It does not change the account UI, planner, shared ID helper, or provider settings protocol. Later base changes share crypto and DPoP code.
  • Tested the exact combined tree f418cea554231d93ce78dad2149c613caf1ed207, using a temporary local merge commit and its pinned dependencies. Client-runtime, mobile, and web typechecks all pass with @effect/tsgo 0.67.1. Existing Effect suggestions remain non-fatal. The focused account, ID, and web-dialog tests pass. No combined-tree runtime pass was run; the attached device recordings still document the unchanged published head.
text
1$ vp run --filter @t3tools/client-runtime --filter ./apps/mobile --filter ./apps/web typecheck
2vp run: 0/1 cache hit (0%), 3/3 successful.
3exit 0
4
5$ vp test run apps/mobile/src/features/settings/claude-accounts.test.ts packages/client-runtime/src/providerInstanceIds.test.ts apps/web/src/components/settings/AddProviderInstanceDialog.test.ts
6Test Files 3 passed (3)
7 Tests 8 passed (8)
8exit 0

Checks

24 successful · 14 skipped
All checks passed
351b8d3

[GPT-6.1 Sol][Codex] on behalf of shivam.

Verification for head e3d746339a1af2525801df5058d3c515e5f60be8:

  • vp run check:changed passed format, lint, knip, affected-package typechecks, 15 tests in 5 files, and React compiler checks. The summary is below.
  • The edit regression assertion failed before the fix for clearing the config folder, then passed. Independent final review found no remaining blockers or should-fix findings and ran 8 focused tests across 3 files successfully.
  • On Android and iOS, checked add, edit, remove confirmation, re-add, and selection of Claude B · Opus with Save and reopen. Android also checked required fields and clearing the config folder. Recordings and exact client fingerprints are in the PR body.
  • Web regression check: the existing wizard derived claudeAgent_claude_b_2 for the colliding name Claude B, then saved that instance with the supplied folder. No shared-helper behavior changed.
  • Reviewed against 88f611368e0166a543b294d69747eefe46fed73e; publication base fa31b66bbb2ae5234205a8628a78e038d917202f changes only unrelated Antigravity wording and idle-compaction documentation in overlapping files. GitHub reports no conflicts.

Authentication status in the picker was simulated with a local no-network CLI fixture. Real authentication, an actual limit-hit continuation, and Windows-server behavior remain unverified.

Changed-file check output
text
1Head: e3d746339a1af2525801df5058d3c515e5f60be8
2Reviewed/tested base: 88f611368e0166a543b294d69747eefe46fed73e
3Publication base: fa31b66bbb2ae5234205a8628a78e038d917202f
4Environment: corex Linux; isolated worktree state
5
6$ node scripts/check-changed.ts ⊘ cache disabled
7check:changed: 11 files since 88f611368e01 (origin/main)
8Runs everything: packages/client-runtime/package.json
9
10> vp unused patches pass 7.1s
11Scope: all 40 workspace projects
12[WARN] 12 deprecated subdependencies found: @oslojs/asn1@1.0.0, @oslojs/binary@1.0.0, @oslojs/cbor@1.0.0, @oslojs/crypto@1.0.0, @oslojs/webauthn@1.0.0, boolean@3.2.0, crypto-js@4.2.0, glob@7.2.3, inflight@1.0.6, lodash.isequal@4.5.0, rimraf@2.6.3, uuid@7.0.3
13[WARN] Issues with peer dependencies found. Run "pnpm peers check" to list them.
14Done in 6.3s using pnpm v12.14.0
15
16> vp format pass 0.8s
17Checking formatting...
18
19All matched files use the correct format.
20Finished in 459ms on 11 files using 16 threads.
21
22> vp lint pass 2.7s
23
24> vp knip 1/2 pass 19.4s
25
26> vp knip 2/2 pass 30.1s
27
28> vp typecheck (39 packages) pass 144.6s
29~/apps/desktop$ tsc --noEmit ◉ cache hit, replaying
30
31~/packages/provider-acp-registry$ tsc --noEmit ◉ cache hit, replaying
32
33~/packages/secret-provider-onepassword$ tsc --noEmit ◉ cache hit, replaying
34
35~/packages/provider-opencode$ tsc --noEmit ◉ cache hit, replaying
36
37~/packages/client-runtime$ tsc --noEmit ◉ cache hit, replaying
38
39~/apps/web$ tsc --noEmit
40
41~/packages/source-control-gitlab$ tsc --noEmit
42
43~/packages/source-control-core$ tsc --noEmit
44
45~/packages/provider-grok$ tsc --noEmit
46
47~/packages/provider-acp$ tsc --noEmit
48
49~/packages/secret-provider-definitions$ tsc --noEmit
50
51~/scripts$ tsc --noEmit
52
53~/packages/source-control-definitions$ tsc --noEmit
54
55~/packages/effect-acp$ tsc --noEmit
56
57~/apps/server$ tsc --noEmit
58
59~/packages/provider-fx$ tsc --noEmit
60
61~/packages/source-control-bitbucket$ tsc --noEmit
62
63~/packages/secret-provider-core$ tsc --noEmit
64
65~/packages/effect-codex-app-server$ tsc --noEmit
66
67~/infra/task-cache$ tsc --noEmit
68
69~/packages/tailscale$ tsc --noEmit
70
71~/packages/source-control-gitcafe$ tsc --noEmit
72
73~/apps/mobile$ tsc --noEmit
74
75~/packages/provider-cursor$ tsc --noEmit
76src/server/adapter.test.ts:86:30 - suggestion TS377096: This generator applies `Effect.orDie` to every yielded effect. Hoist it once to the generator result: `Effect.gen(...).pipe(Effect.orDie)`, or `Effect.fn(function*(){ ... }, Effect.orDie)`. effect(redundantOrDie)
77
7886 Effect.gen(function* () {
79 ~~~~~~~~~
80
81 src/server/adapter.test.ts:118:31 - This repeated `Effect.orDie` site participates in the hoistable generator-wide `orDie`. effect(redundantOrDie)
82 118 }).pipe(Effect.orDie);
83 ~~~~~~~~~~~~
84
85 src/server/adapter.test.ts:146:58 - This repeated `Effect.orDie` site participates in the hoistable generator-wide `orDie`. effect(redundantOrDie)
86 146 yield* input.onDelta!(update).pipe(Effect.orDie);
87 ~~~~~~~~~~~~
88
89
90~/packages/source-control-azure-devops$ tsc --noEmit
91
92~/packages/source-control-github$ tsc --noEmit
93
94~/packages/provider-testing$ tsc --noEmit
95
96~/packages/ssh$ tsc --noEmit
97
98~/infra/relay$ tsc --noEmit
99
100~/apps/marketing$ astro check
10121:38:28 [types] Generated 1.30s
10221:38:28 [check] Getting diagnostics for Astro files in <worktree>/apps/marketing...
103Result (22 files):
104- 0 errors
105- 0 warnings
106- 0 hints
107
108
109~/packages/source-control-forgejo$ tsc --noEmit
110
111~/packages/shared$ tsc --noEmit
112
113~/packages/provider-core$ tsc --noEmit
114
115~/packages/contracts$ tsc --noEmit
116
117~/packages/provider-pi$ tsc --noEmit
118
119~/packages/source-control-testing$ tsc --noEmit
120
121~/evals$ tsc --noEmit
122
123~/packages/provider-muse$ tsc --noEmit
124
125~/oxlint-plugin-t3code$ tsc --noEmit
126
127---
128vp run: 5/39 cache hit (12%), 39/39 successful, 7.38s saved. @t3tools/scripts#typecheck (and 1 more) not cached because they modified their inputs. (Run `vp run --last-details` for full details)
129
130> vp test (5 files) pass 40.4s
131
132 RUN v5.0.5 <worktree>
133
134
135 Test Files 5 passed (5)
136 Tests 15 passed (15)
137 Start at 21:39:23
138 Duration 34.66s (transform 40%, setup 24%, import 16%, worker 16%, tests 4%)
139
140> vp react compiler (5 files) pass 23.7s
141
142 RUN v5.0.5 <worktree>
143
144
145 Test Files 2 passed (2)
146 Tests 10 passed | 2306 skipped (2316)
147 Start at 21:40:02
148 Duration 19.63s (transform 42%, tests 37%, setup 13%, import 8%)
149
150check:changed summary
151 pass unused patches 7.1s
152 pass format 0.8s
153 pass lint 2.7s
154 pass knip 1/2 19.4s
155 pass knip 2/2 30.1s
156 pass typecheck (39 packages) 144.6s
157 pass test (5 files) 40.4s
158 pass react compiler (5 files) 23.7s
159 CI also runs: full test suites, build, rust, release smoke
160 pass not cached: files changed during the run
Synced from GitHub

Approvability

Verdict: Approved at e3d7463

Macroscope's review found this PR approvable — Mobile users can configure additional Claude accounts using server folders that are already signed in. The controls reuse existing provider settings operations, leave credentials intact on removal, and do not change product defaults.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Mobile Settings now supports adding and editing Claude provider accounts and removing eligible non-default accounts. Shared provider-instance ID derivation is exported from client-runtime and used by the web provider dialog. The Claude provider guide documents the mobile setup path.

Changes: Claude account management

Layer / File(s)Summary
Shared provider-instance ID derivation
packages/client-runtime/src/providerInstanceIds.ts, packages/client-runtime/src/providerInstanceIds.test.ts, packages/client-runtime/package.json, apps/web/src/components/settings/AddProviderInstanceDialog*
Client-runtime now provides and exports provider-instance ID derivation helpers. The web provider dialog imports these helpers instead of using local implementations.
Claude account save planning
apps/mobile/src/features/settings/claude-accounts.ts, apps/mobile/src/features/settings/claude-accounts.test.ts
The save planner validates new account fields, checks managed policy, and creates or updates provider instances. Tests cover creation, edits, validation, and policy checks.
Mobile account management and provider routing
apps/mobile/src/features/settings/ClaudeAccounts.tsx, apps/mobile/src/features/settings/SettingsProviderAccountsRouteScreen.tsx, docs/user/providers-claude.md
Mobile Settings displays and manages Claude accounts, with mutation status and confirmation for removal. Provider routing renders Claude accounts when permitted. The guide describes adding an account from mobile Settings.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant User
3 participant SettingsProviderAccountsRouteScreen
4 participant ClaudeAccount
5 participant planClaudeAccountSave
6 participant ProviderInstanceMutationHook
7 participant Environment
8 User->>SettingsProviderAccountsRouteScreen: Open provider settings
9 SettingsProviderAccountsRouteScreen->>ClaudeAccount: Render Claude account controls
10 User->>ClaudeAccount: Submit account draft
11 ClaudeAccount->>planClaudeAccountSave: Plan save with draft and policy
12 planClaudeAccountSave-->>ClaudeAccount: Return mutation or validation error
13 ClaudeAccount->>ProviderInstanceMutationHook: Submit planned mutation
14 ProviderInstanceMutationHook->>Environment: Send provider-instance mutation
15 Environment-->>ProviderInstanceMutationHook: Return mutation result
16 ProviderInstanceMutationHook-->>ClaudeAccount: Return success or failure

Possibly related issues

  • pingdotgg/t3code#28872 — The issue requests a mobile way to configure or select another Claude login. This change adds mobile account configuration using an existing signed-in Claude config folder.
  • pingdotgg/t3code#29414 — The issue reports a provider removal action without a label or confirmation. This change adds a labeled removal action with confirmation for eligible Claude accounts.

Suggested reviewers: juliusmarminge, maria-rcks

Merge Risk: External image Minimal · up to 351b8

Separate Claude configuration folders can be managed from mobile settings. No merge-blocking risk was identified.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title "fix(mobile): configure another Claude account from Providers" matches the main change. The PR lets mobile Settings > Providers list, add, edit, and remove Claude instances (Claude config fo…
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Description checkPassedThe description covers every required template section. Problem: mobile Settings → Providers omits Claude, so users cannot register another signed-in Claude config folder from the phone. Change: lists…
Full details: Title check

Explanation

The title "fix(mobile): configure another Claude account from Providers" matches the main change. The PR lets mobile Settings > Providers list, add, edit, and remove Claude instances (Claude config folders), which the title describes. It uses a conventional commit prefix, is one sentence, and avoids vague terms. The title does not mention the shared ID helper extraction or the web wizard change, but those are secondary details.

Full details: Description check

Explanation

The description covers every required template section. Problem: mobile Settings → Providers omits Claude, so users cannot register another signed-in Claude config folder from the phone. Change: lists Claude instances and lets users add, edit, and remove them through the existing environment-scoped server command and permissions, with the shared ID helper extracted for web. Scope and approval: it references issue #28872, but the template asks for a triaged issue or discussion with explicit maintainer approval of direction and scope, including the approval comment. The description links the issue without stating that a maintainer approved it. Verification: it lists focused tests (three test files, eight tests passing), a combined-tree typecheck, Android and iOS device runs, and a Windows pass, with screenshots and recordings. It also states what was not verified (real Claude authentication, quota recovery, context handoff). The PR body also says that the failing items were checked in the base-compatibility recheck. The description does not include a conventional commit title, and the PR title is outside the description body. The 'Implemented with' line identifies the model and harness, as the template requests. Overall the description is thorough and mostly complete; the main gap is the approval evidence.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between e3d746339a1af2525801df5058d3c515e5f60be8 and 351b8d356635eb6c48f0ba4a4fda17790d42579d.

External image Files selected for processing: 1
  • apps/mobile/src/features/settings/SettingsProviderAccountsRouteScreen.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

Added 2 commits

  • feat(mobile): add another Claude account from Providers settings2595bdb
  • fix(mobile): reset Claude account config folder when cleared351b8d3