fix(mobile): show the provider account badge on thread rows - #9899
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9673c6c. Configure here.
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused client-side UI enhancement that adds account badges to mobile thread rows while preserving existing provider routing and single-instance presentation; its shared display logic is small, tested, and has no schema, deployment, security, billing, or static-analysis impact. The supplied medium findings concern account-label disambiguation and Unicode initials, and the head includes the corresponding shared fallbacks and tests. Notes:
No code changes detected at You can add or adjust custom eligibility rules. Learn more. |
9673c6c to
31e9fd1
Compare
0685e1f to
d3fcee6
Compare
There was a problem hiding this comment.
All clear
Posted via Macroscope — Effect Service Conventions
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe change centralizes provider-instance display logic, resolves provider instances for mobile threads, and renders account badges in mobile home and sidebar thread rows. It also adds branch-thread actions and swipeable lifecycle updates. ChangesProvider instance badges
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to Mobile thread rows now display provider account badges and configured accents, improving account identification without an identified current-head merge risk. Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Out of Scope Changes checkExplanation The pull request includes changes not required by issue ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
d3fcee6 to
0753eb9
Compare
There was a problem hiding this comment.
All clear
Posted via Macroscope — Effect Service Conventions
|
All clear Posted via Macroscope — Effect Service Conventions |
ddbca06 to
514d950
Compare
This comment has been minimized.
This comment has been minimized.
Thread rows drew a bare provider glyph, so two accounts on the same provider looked identical. Rows now carry the same accent-color initials badge the web sidebar shows, driven by the badge rule shared through client-runtime so the two clients cannot drift. Built with Claude Fable 5.1 in Claude Code.
514d950 to
1533e05
Compare
Merges `pingdotgg/t3code` `8b2838e0e..a37c664` — 43 commits. `343` files landed against `343` changed in the upstream range; fork delta `723` files. Exact match, so nothing upstream changed was dropped. Details in [`docs/fork/upstream-merge-log.md`](../blob/merge/upstream-2026-09-08/docs/fork/upstream-merge-log.md). ## Two fork deltas this merge had to re-apply **Upstream split the server-update banner into two routes.** pingdotgg#10596 added `useAutoBalanceUpdateBanner` beside the single-machine condition the fork already gates. The conflict was on the first line only, so resolving it correctly still left the auto-balance route ungated — an auto-balanced project would have been offered `npx t3` against a backend that does not implement `server.updateServer`. `FEATURES.serverUpdateBanner` now carries two gates in `ChatView.tsx`. **A new settings page needs a gate even though it degrades politely.** pingdotgg#8103 added `/settings/snap-shot` for desktop window capture. Every control drives `window.desktopBridge`, and upstream renders an "unavailable" notice rather than hiding the page, so a hosted build listed a sidebar section and six searchable rows for a feature it can never run. Gated with `FEATURES.snapShots`. Two smaller fixes: `packages/moatless-api` still ran `tsgo --noEmit` after upstream replaced `@typescript/native-preview` with TypeScript 7.0.2, and `duplicate-adds.mjs` now skips `pnpm-lock.yaml` (it read `iconv-lite: 0.6.3` as taken twice; `d3-dsv` and `encoding` each declare it). ## Usable as-is - Stop-thread keybinding command (pingdotgg#4308). - Project import tolerates servers that predate the git-identity scan (pingdotgg#10547). - Proactive panels open when entering a thread (pingdotgg#10610); pull-request markdown links open in the panel (pingdotgg#10623); markdown images navigate as galleries (pingdotgg#10625); pull-request videos play inline (pingdotgg#10617). - Settings project scopes are searchable and scrollable (pingdotgg#10570); ref picker stays steady when opening (pingdotgg#9472); sidebar timer uses `tabular-nums` (pingdotgg#10592); popup triggers stay steady when pressed (pingdotgg#9468); settled PR colors restore on hover (pingdotgg#10023). - Composer Fast mode persists across new chats (pingdotgg#2981); inserted citations are removed on cancel (pingdotgg#10518). - TypeScript 7.0.2 (pingdotgg#10663) and the knip desktop-export rules (pingdotgg#10269). ## Unsupported in Moatless / needs implementation - **Cross-platform window capture** (pingdotgg#8103) — `apps/desktop/src/snapShot/**`, `apps/web/src/components/settings/SnapShotSettings.tsx`, `apps/web/src/lib/desktopSnapShot.ts`. Needs an Electron `window.desktopBridge`; a browser tab has none. Gated behind `FEATURES.snapShots` in this PR. - **Auto-balance server update** (pingdotgg#10596) — `apps/web/src/components/chat/useAutoBalanceUpdateBanner.tsx`. Needs `server.updateServer`, which Moatless does not dispatch. Gated behind `FEATURES.serverUpdateBanner` in this PR. - **Preview recording transfer** (pingdotgg#10572) — `apps/server/src/mcp/toolkits/preview/handlers.ts`, `apps/web/src/browser/browserRecordingUpload.ts`. Moves a finished preview recording into the agent environment over the desktop bridge. Adds four error types to `packages/contracts/src/previewAutomation.ts` and no new RPC method, so no union changed. Sits behind the `previewAutomation.connect` / `focusHost` / `respond` gap already in the register. - **Local media linked from remote threads** (pingdotgg#10619) and **browser editing shortcuts** (pingdotgg#10621) — Electron shell only. - **iOS Keychain access group** (pingdotgg#3665) and the mobile provider account badge (pingdotgg#9899) — the fork ships no mobile build against Moatless. ## Backend behavior to consider reproducing in Moatless - **Name the usage limit and its reset instead of relaying "out of credits"** (pingdotgg#10473, `apps/server/src/provider/**` Codex adapter). Moatless owns its provider runtime, so the clearer limit message has to be produced there. - **Report usage limits on retried turns** (pingdotgg#10549, Claude adapter). A retry currently loses the limit signal; same ownership. - **Disable executable capabilities in Claude metadata generation** (pingdotgg#4169, `apps/server/src/textGeneration/ClaudeTextGeneration.ts`). Title and metadata generation should not be able to run tools. Worth mirroring wherever Moatless generates thread titles. ## Verification `verify.mjs`: duplicate-adds, tripwires, resolution-check, unsupported-methods (0 ADD, 0 DROP, 2 KEEP), fmt, lint and typecheck all pass. Tests pass except `@t3tools/desktop`, which cannot compile `scripts/browser-secret-native.test.mjs` because the sandbox has no `libsecret-1` — 1283 tests pass, 0 fail, and the file is byte-identical to upstream. New entry in `docs/fork/gaps.md`. `t3` failed `GrokAdapter.test.ts` once under parallel load and passes 42/42 alone. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/6d8ea486-2fcb-4c25-bd34-dcd15cc4a7ac

What Changed
Mobile thread rows now show which provider account a thread runs on, the way the web sidebar has since #5980. When an instance has an accent color, or several instances share one provider, the provider glyph carries the account's accent badge with its initials. Rows for a single plain instance look exactly as before.
The badge rule and the instance label rule move from the web app into
client-runtime, so web and mobile name and badge an instance identically. Web keeps its call sites. Mobile replaces the inline provider lookup in the Home list and the iPad sidebar with one resolver that returns the driver, label, accent, and badge flag, scoped to the thread's own environment because default instance ids collide across servers. The legacy v1 list never drew a provider glyph and is left alone.Fixes #9898.
Why
With a work and a personal subscription on the same provider, the phone was the one client where you could not tell them apart. The row rendered a dimmed glyph, and an accent color set on the server never appeared on mobile. The data was already on the device; the row only received the driver and dropped the display name and accent on the way.
Review guide
Eleven files, one concern. Read in this order:
packages/client-runtime/src/state/providerInstanceDisplay.ts(new) —shouldShowInstanceBadge,normalizeProviderAccentColor,providerInstanceInitials, and the instance label rule, moved verbatim fromapps/web/src/providerInstances.tsandProviderInstanceIcon.tsx. Only two behavior changes: initials iterate by code point so an emoji name does not split, and the label fallback (humanize a non-default instance id when the server sent the brand label) is now shared instead of web-only. Exported as@t3tools/client-runtime/state/provider-instance-display.apps/web/src/providerInstances.ts,apps/web/src/components/chat/ProviderInstanceIcon.tsx— import from the shared module and re-export the old names. No web call site changes.apps/mobile/src/features/threads/thread-provider-instance.ts(new) —resolveThreadProviderInstance(serverConfigs, thread), the one lookup both lists use.apps/mobile/src/components/ProviderIcon.tsx—ProviderInstanceIcon: the existing glyph at 60% opacity plus the corner badge, same geometry as web.apps/mobile/src/features/threads/thread-list-v2-items.tsx,HomeScreen.tsx,ThreadNavigationSidebar.tsx— the row takes the resolved instance instead of a driver string; each screen swaps its inline.find(...)for the resolver.Risk is low: client-only, no contract or persistence change. The only web-visible effect is that
deriveProviderInstanceEntriesnow calls the shared label resolver, which is the same code it called before.UI Changes
Same server, same threads, one Claude Code account with a green accent color.
No motion changes, so no video.
Verification
vp test run packages/client-runtime/src/state/providerInstanceDisplay.test.ts apps/mobile/src/features/threads/thread-provider-instance.test.ts apps/web/src/providerInstances.test.tsChecklist
Written by Claude Fable 5.1 in Claude Code.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Note
Show provider account badge on mobile thread rows
ProviderInstanceIconto mobile, which dims the provider glyph and overlays an account badge with initials and accent colorresolveThreadProviderInstanceto resolve environment-scoped provider metadata (display name, accent color, badge visibility) for each thread row; HomeScreen and ThreadNavigationSidebar now pass this metadata to rowsThreadListV2Rowinput changed from a driver string toThreadRowProviderInstancemetadata — any caller not updated viaHomeScreenorThreadNavigationSidebarwill fail to compileMacroscope summarized 1533e05.