feat(web): split provider settings into list and editor - #8380
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
There was a problem hiding this comment.
Reviewed the Providers page rework against the shared control system. Five consistency issues in the new interactive markup, mostly around clickable affordances and half-wired ARIA tab semantics. Layout/Tailwind ownership itself looks fine.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
UI consistency review
Five findings, all in the new provider settings layout. The main themes: the new tab bars and the "Advanced" disclosure hand-roll behavior that the shared primitives already own (focus-visible ring, pointer cursor, coarse hit target, trigger/panel ARIA wiring, panel transition), and ARIA tab roles are applied without the panel association or keyboard model they promise.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
One finding: the new editor header drops the provider status/diagnostic line that the removed auth row used to render, so getProviderSummary().detail is no longer rendered anywhere on the page. Everything flagged in earlier runs (tab/tablist ARIA, the hand-rolled Advanced disclosure, the size="sm" override on the Add provider button, the always-empty Models tab) reads as resolved on this head.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Reviewed the providers page rework for shared-primitive ownership, Tailwind ownership, and preserved interaction/accessibility semantics. The earlier ARIA/tab-role, cursor, Collapsible, and Button size findings are addressed in this revision. Three remaining items: status detail that no longer renders anywhere, a status dot that is now explained only to screen readers, and two new tab strips implemented two different ways.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
UI consistency review of the providers settings rework. The earlier ARIA/tab-role, cursor, Collapsible, and button-geometry items are resolved in dd06a1b. Two regressions introduced by the removed header content remain.
Posted via Macroscope — UI Consistency
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This production-facing redesign changes provider selection, editing, device navigation, read-only behavior, and status presentation across the existing settings flow. Its new master-detail workflow and broad UI/runtime impact are beyond a small isolated adjustment. You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
One finding: the new device tab strip uses a raw overflow-x-auto lane, unlike the other horizontally-overflowing strips in this app, so a native horizontal scrollbar can land on top of the active-tab underline. Everything else in this revision (tabs now aria-pressed with cursor-pointer + focus ring, tooltip restored on the icon-only refresh action, Collapsible* used for the Advanced disclosure, size="compact" for Add provider, editor-side status line) reads consistently with the shared primitives.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Reviewed the provider settings rework for shared-primitive and Tailwind-ownership consistency. The concerns raised on earlier pushes look addressed: the tab strips now use aria-pressed (no half-implemented role="tab" contract) plus cursor-pointer and a focus-visible ring, the Advanced disclosure is back on the shared Collapsible/CollapsibleTrigger/CollapsibleContent primitives, the refresh action regained its Tooltip, the "Add provider" button uses the named compact size, the device strip hides its scrollbar with the same arbitrary-utility pattern already used by BrowserDeviceToolbar/PullRequestDetailPanel, and ConnectionStatusDot renders a span (no nested button) with the status wording surfaced via the wrapping tooltip. One small layout artifact left, noted inline.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
One finding on the new device tab strip: it copies ScrollArea's hideScrollbars utilities onto a bare overflow-x-auto div without the overflow-aware fade the shared primitive owns.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
One finding: the update-available affordance lost its motion cue during the popover-trigger move. Everything else previously raised (device-strip scroll fade via ScrollArea, list/footer border seam, tooltip on the icon-only refresh action, editor-side status text, Collapsible for the Advanced disclosure, named Button sizes, aria-pressed tab semantics with cursor-pointer + focus ring) now matches the shared component system.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Reviewed the Providers settings redesign for shared-primitive, Tailwind-ownership and accessibility consistency. The earlier tab-semantics, Collapsible, ScrollArea and refresh-tooltip points now look addressed; two remaining items on the device strip and the Advanced disclosure.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Reviewed the providers page restructure for shared-primitive ownership, Tailwind ownership, and interaction preservation. The shared providerSettingsTabClassName helper, the ScrollArea device strip, and the Collapsible-based Advanced disclosure all now route through the shared contracts. Two findings remain, both in ProviderSettingsPanel.tsx.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Two findings on the read-only handling added in the latest commits.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
One finding: the new shared tab class relies on an outward focus ring inside a clipping scroll viewport, so keyboard focus on the device tabs is nearly invisible. Details inline.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
One finding on the new environment-draft resync in ProviderInstanceCard.tsx. Previously flagged issues (tab strip reachable in read-only, greying scoped to the inert subtrees, inset focus ring in providerSettingsTabClassName) look resolved.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high 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 123fb56. Configure here.
There was a problem hiding this comment.
Two regressions in the new provider list/editor split: the read-only wrapper now blocks the editor's tab strip, and the environment-variable section resyncs from prop identity that changes on every parent render.
Posted via Macroscope — UI Consistency
## What's Changed * Fix Android adaptive launcher icon by @colonelpanic8 in pingdotgg/t3code#4332 * feat(web): split provider settings into list and editor by @t3dotgg in pingdotgg/t3code#8380 ## New Contributors * @colonelpanic8 made their first contribution in pingdotgg/t3code#4332 **Full Changelog**: pingdotgg/t3code@v0.0.36-nightly.20260827.1206...v0.0.36-nightly.20260827.1207 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.36-nightly.20260827.1207
Rewrites FORK.md around the four sections it is meant to carry — purpose, last rebase, the numbered changes with their intent, and what upstream has since superseded — and trims the per-entry prose to the decisions a re-derivation would otherwise get wrong. Entry numbers are unchanged; nothing was superseded in this range, so section 4 only moves its "verified at" column. Records what actually needed re-deriving: upstream pingdotgg#8380's provider settings rewrite (entry 15), pingdotgg#8358's Grok usage support (entries 16 and 19, including why the usage contract went to 6 and took `USAGE_MERGE_COMPATIBLE_SINCE` with it), pingdotgg#8144's compaction control sharing entry 22's popover, and the decision to decline `desktop-macos-preview.yml` under entry 14's opt-in rule. Refreshes the README banner's rebase marker and its summary, which had not caught up with entries 21 and 22, and fixes the ci.md line naming the wrong job as the source of the thread-transfer artifact — it is Test Server, the sharded job entry 14 warns against renaming. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzCcc9XJPsJL14c2sxa7sM
Upstream a6797b3..c8aba25 (11 commits). Re-hosted the fork's provider settings features into upstream's pingdotgg#8380 list/editor split, hoisting the pending-envelope stale-write protection to a panel-owned map shared by both card mounts. Kept fork tests for mobile branding and sidebar width. Fixed two pre-existing dev suite failures from the 2026-08-27 voice PRs (missing --color-accent runtime variable, missing listening-module mocks). Merged by Claude Fable 5 via Claude Code with gpt-5.6-sol implementation and opus-5 audit.
## What's Changed * fix(grok): improve skills, plans, usage, and turn reliability by @t3dotgg in pingdotgg/t3code#8358 * fix(server): recover stale Codex approval callbacks by @luckyPipewrench in pingdotgg/t3code#5195 * test(server): remove duplicate missing worktree test by @t3-code[bot] in pingdotgg/t3code#8252 * fix(server): replay all un-applied events during projection bootstrap by @krutftw in pingdotgg/t3code#7538 * test: remove low-signal test files by @t3-code[bot] in pingdotgg/t3code#8397 * test: prune trivial error and layout tests by @t3-code[bot] in pingdotgg/t3code#8400 * Fix Android adaptive launcher icon by @colonelpanic8 in pingdotgg/t3code#4332 * feat(web): split provider settings into list and editor by @t3dotgg in pingdotgg/t3code#8380 * fix(codex): accept Codex 0.150 account plans by @gsimone in pingdotgg/t3code#8447 * fix(tooling): allow ignored-only staged changes by @juliusmarminge in pingdotgg/t3code#8468 * fix(mobile): keep iOS home header stable by @juliusmarminge in pingdotgg/t3code#8467 * fix(web): stop showing red x summaries for ordinary tool failures by @t3dotgg in pingdotgg/t3code#8395 * fix(mobile): refine Git action toast glass styling by @juliusmarminge in pingdotgg/t3code#8399 * fix(desktop): allow preview automation in agent-created threads by @t3dotgg in pingdotgg/t3code#8483 * test(web): remove redundant cache key test by @t3-code[bot] in pingdotgg/t3code#8484 * fix(release): move nightly schedule to minute 38 by @t3dotgg in pingdotgg/t3code#8509 * fix(web): stabilize the provider settings editor by @t3dotgg in pingdotgg/t3code#8472 * fix(web): open GitHub pull requests in browser when loading fails by @t3dotgg in pingdotgg/t3code#8507 * fix(codex): show sub-agent models by @t3dotgg in pingdotgg/t3code#8502 * feat(analytics): report connected client platforms by @t3dotgg in pingdotgg/t3code#8481 * feat(server): accept PDF, ZIP, and other file uploads up to 50MB by @t3dotgg in pingdotgg/t3code#8235 * feat(web): toggle a thread's pin from the keyboard by @ipanasenko in pingdotgg/t3code#8440 * fix(web): add back button to project settings by @StiensWout in pingdotgg/t3code#8168 * refactor(mobile): compile semantic themes for Uniwind by @juliusmarminge in pingdotgg/t3code#7327 * fix(desktop): Cache Runtime locally on WSL Filesystem, dramatically improving launch times by @ikifar2012 in pingdotgg/t3code#5769 * fix(mobile): show OpenCode model sources in picker by @juliusmarminge in pingdotgg/t3code#8573 * fix(clients): honor project default models in new threads by @anirudhsama in pingdotgg/t3code#6011 * fix(mobile): show file actions on Android by @none23 in pingdotgg/t3code#8215 * fix(connect): explain DPoP connection failures by @extoci in pingdotgg/t3code#8351 * feat(web): make the sidebar project filter a searchable combobox by @SunkenInTime in pingdotgg/t3code#5931 * fix(server): a draft can retry its first send after a failed bootstrap by @shivamhwp in pingdotgg/t3code#8226 * fix(desktop): stop hidden previews draining battery by @Bil0000 in pingdotgg/t3code#8567 * fix(desktop): oauth popups open from the browser preview by @walid-baharwal in pingdotgg/t3code#8435 * fix(web): keep long task drawers usable on small screens by @shivamhwp in pingdotgg/t3code#8313 * fix(opencode): handle child approvals, stops, and model catalogs by @t3dotgg in pingdotgg/t3code#8480 * fix: make thread auto-settling opt-in by @shivamhwp in pingdotgg/t3code#8321 * fix(web): stop session activity timing test from blocking releases by @t3dotgg in pingdotgg/t3code#8585 * fix(mobile): show composer menus when starting a task by @juliusmarminge in pingdotgg/t3code#8587 * fix(web): show the configured stash shortcut by @UtkarshUsername in pingdotgg/t3code#8437 * feat(web): add toggleable confirmation before unpinning a thread by @UtkarshUsername in pingdotgg/t3code#7313 * fix: restore automatic thread settling defaults by @t3dotgg in pingdotgg/t3code#8596 * fix(mobile): restore composer glass and rounded shadows by @juliusmarminge in pingdotgg/t3code#8597 ## New Contributors * @luckyPipewrench made their first contribution in pingdotgg/t3code#5195 * @krutftw made their first contribution in pingdotgg/t3code#7538 * @colonelpanic8 made their first contribution in pingdotgg/t3code#4332 * @ikifar2012 made their first contribution in pingdotgg/t3code#5769 * @walid-baharwal made their first contribution in pingdotgg/t3code#8435 **Full Changelog**: pingdotgg/t3code@v0.0.35...v0.0.36 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.36
Merges 58 upstream commits (`badae6a5c` → `6a9d9f988`, upstream v0.0.34 → v0.0.36) through the `fork-upstream-merge` skill. `merge-stats.mjs` reconciles exactly: **431 files landed** against **431 in the upstream range**, no gap to explain. Fork delta is 611 files. ## Conflicts Three, plus one git resolved silently and wrongly. - **`Sidebar.tsx`** — upstream replaced the project picker's `Menu`/`MenuRadioGroup` with a searchable `Combobox` (pingdotgg#5931). Took upstream's structure and re-applied only the `FEATURES.projectManagement` gate on "New project", now carrying the `// Fork:` marker it had been missing. Upstream has since grown the mobile touch-target span itself, so the Mobile Touch Delta has nothing left to re-apply here — one convergence, unprompted. - **`ProviderSettingsPanel.tsx`** — upstream split provider settings into list and editor (pingdotgg#8380, pingdotgg#8472), moving `ProviderLastChecked` and the refresh button out of `headerAction` into the list footer. Took upstream's and re-applied the gate as `!readOnly && FEATURES.serverAdministration`. - **`pnpm-lock.yaml`** — took upstream's and re-ran `vp i`, which restored the fork's `@t3tools/moatless-api` workspace edge. - **`packages/contracts/src/orchestration.test.ts`** — auto-merged, no marker, broken. Both sides appended `OrchestrationMessage` to the same import list and the same `decodeOrchestrationMessage` const at different offsets, so git took both. Surfaced as a parse error in lint, typecheck and test at once. This is the case `merge-stats.mjs`'s conflict-candidate list exists to catch. `HostedBrowserFrame.tsx` (fork-only) also needed the `renderingActive` prop pingdotgg#8567 made required. Upstream suspends a parked webview unless background audio, PiP or a recording still needs it painted; a frame has none of those to read and is the app's only copy of the preview page, so it passes `true` and keeps today's behavior. ## Sweep Five keyword hits, all false positives: - `apps/web/src/connection/clientMetadata.ts` + test — reports the client's OS/browser/device on connect (pingdotgg#8481). Auth-adjacent, but it rides `ClientPresentation` on the relay and remote-bearer bootstraps; the fork's primary environment sends none of it. - `packages/client-runtime/src/relay/errorPresentation.ts` + test, `connection/errors.test.ts` — explain DPoP failures (pingdotgg#8351). Relay only, and T3 Connect is decided out. ## Feature classification **Usable as-is** - Searchable project-filter combobox in the sidebar (pingdotgg#5931). - Long task drawers stay usable on small screens (pingdotgg#8313) — directly relevant, the fork's phone story is `apps/web` in mobile Safari/Chrome. - Toggleable confirmation before unpinning a thread (pingdotgg#7313); toggle thread pin from the keyboard. - Back button in project settings (pingdotgg#8168); the configured stash shortcut is shown (pingdotgg#8437). - No more red-x summaries for ordinary tool failures (pingdotgg#8395); PRs open in the browser when loading fails (pingdotgg#8507). - Project default models are honored in new threads (pingdotgg#6011). - Provider settings split into list and editor (pingdotgg#8380, pingdotgg#8472) — landed, though `/settings/providers` is itself gated behind `serverAdministration`. **Unsupported in Moatless / needs implementation** - **Non-image file attachments** (pingdotgg#8235) — a turn may now carry any file up to 50MB, advertised as `capabilities.fileAttachments.maxUploadBytes` and sized by `PROVIDER_SEND_TURN_MAX_FILE_BYTES`. Moatless advertises neither this nor `attachmentUploads`, so the composer's attach affordance stays off. Costs nothing today (upstream's own web composer offers images only; `ChatAttachment` widened just far enough to typecheck), but it is the second capability key to report when uploads land. Extends the existing **Attachment uploads** entry in `docs/fork/gaps.md`. - **Connected-client platform analytics** (pingdotgg#8481) and **DPoP failure explanations** (pingdotgg#8351) — relay and T3 Connect surfaces, already decided out of the fork. No new WS methods entered the contract in this range, so no new `UnsupportedMethodError` union entries. `unsupported-methods.mjs` reports `ADD 0`, `DROP 1` (`scripts.run`), `KEEP 2`. The `scripts.run` DROP is **not** actioned — it is the documented exception in the gaps register: that union entry answers for `apps/server`, which still stubs the method (verified surviving in `ws.ts`), not for Moatless. **Backend behavior to consider reproducing in Moatless** - **Replay all un-applied events during projection bootstrap** (pingdotgg#7538) — a one-line pipeline fix upstream; Moatless runs its own projection and the same class of bug applies. - **A draft can retry its first send after a failed bootstrap** (pingdotgg#8226) — Moatless owns turn start, and a draft wedged by a failed bootstrap is the same dead end here. - **Recover stale Codex approval callbacks** (pingdotgg#5195) — Moatless owns the agent runtime in the sandbox. - **Stop querying Claude context usage after turns** (pingdotgg#8610) — a cheap correctness/cost fix in the same place Moatless polls. - **Server-side accept and size-limit non-image uploads** (pingdotgg#8235), the other half of the gap above. - Auto-settling churn (pingdotgg#8321 made it opt-in, pingdotgg#8596 reverted) nets to no change — noted so the next merge does not re-derive it. ## Verification `verify.mjs`: `tripwires`, `fmt:check`, `lint`, `typecheck` pass. `test` reports `@t3tools/web` **flaky, passed alone** — in the full run `MessagesTimeline.test.tsx` skipped all 34 tests on a 30s module-import timeout under `ChatMarkdown.tsx`; alone the package is 297 files / 3117 tests green. Load, not the merge. `inventory-check.mjs` clean. Model: Claude Opus 5, via Claude Code in a Moatless sandbox. --- Moatless task: https://moatless.soaplabstest.com/tasks/a0c041bb-1426-4591-9296-6a4b0cfa2eff

Provider settings spread status, switches, and detailed controls down one long page. It was hard to scan providers or switch between configurations.
This changes the page to a two-column layout. The left side keeps every provider and its on/off switch visible. The right side edits one provider through separate Models and Configuration tabs. Device selection moves to compact tabs, while the health check interval stays available under Advanced.
Before
After
Checks
vp run --filter @t3tools/web typecheckBuilt with GPT-5.6 Sol in the Codex harness.
Note
Medium Risk
UI and props contract changes for provider configuration editing, including environment-variable draft sync; behavior changes for disabled status display but no server-side auth or persistence logic.
Overview
Provider settings move from a single scroll of expandable cards to a master–detail layout: a left Provider list (status, enable switch, selection) and a right editor for the selected instance.
ProviderInstanceCarddrops expand/collapse in favor ofmode: "list" | "editor"plusselected/onSelect/readOnly. The editor uses Models and Configuration tabs instead of one collapsible block. Disabled instances always show a neutral Disabled summary and muted status dot (not stale server status). Authenticated-email /ProviderAuthEmailUI is removed; warning/error status appears only in the editor header.ProviderSettingsPanelwires selection state, puts device picking in a horizontal tab bar above Providers (replacing the device card grid), moves health check interval into an Advanced collapsible, and scopesinertto editor/advanced areas so list selection still works in read-only mode.ProviderEnvironmentSectionresyncs local env-var rows when the parentenvironmentprop changes (with equality checks to avoid fighting in-flight edits). Shared tab styling lives inproviderSettingsTabs. Tests are updated for list/editor flows and read-only behavior.Reviewed by Cursor Bugbot for commit f6ca5be. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Split provider settings into master-detail list and editor views
ProviderInstanceCardwith two modes:list(compact selectable row with enable switch) andeditor(full detail with Models/Configuration tabs). Callers must update to the newmode,selected,onSelect, andreadOnlyprops.EnvironmentProviderSettingsinto a two-column layout where the left pane lists instances and the right pane shows the selected editor. Devices are selected via a top tab bar instead of a grid, and the page layout is widened.ProviderEnvironmentSectionto preserve in-progress edits whenenvironmentprop re-renders with equivalent data, using the newproviderEnvironmentsEqualhelper.ProviderAuthEmailcomponent and changes disabled provider status dot from amber to muted.ProviderInstanceCardPropsinterface changed fromisExpanded/onExpandedChangetomode/selected/onSelect/readOnly; any out-of-tree callers will break. Read-only mode keeps selection active but disables modification viainert/aria-disabled.Macroscope summarized f6ca5be.