chore: remove dead code, legacy features, and unearned options - #23
Merged
Conversation
Twelve source files had no importer anywhere in the repo, and none has a sibling test. They are dead upstream too, so upstream rarely touches them and deleting them costs us little at cherry-pick time. Two of them, ThreadTerminalPanel and GlassSafeAreaView, were last touched upstream by the deferred Uniwind refactor (#7327). Removing them now shrinks that pick's surface. announce-connect-ga.ts mails a Connect GA announcement to a private-beta waitlist. That waitlist is upstream's; RAS Code never ran one. .macroscope/ configures upstream's review bot, which does not run here.
LegacySidebar was a second 3.7k-line sidebar sitting beside Sidebar.tsx, selected by the `legacySidebarEnabled` client setting. Nothing rendered a toggle for it: the "Settings → General → Legacy features" section the code comments pointed at does not exist, so the only way in was hand-editing a settings blob. It was not free to keep. Upstream still changes it, most recently on 2026-08-28, so every sidebar and composer cherry-pick had to be applied twice. Dropping the schema key is safe for stored settings; decoding already discards keys it does not know, which is how the preceding sidebarV2 keys were retired. With the flag gone the chat.new keybinding always prefers the command palette when there is more than one project group.
Mobile shipped two thread lists side by side: the v2 flat list, on by default, and the original grouped list behind Settings → Legacy → Legacy Thread List. Home, the navigation sidebar, and the header each carried both paths and branched on the preference at 28 sites. Keeping the grouped list also kept its whole model alive: per-group collapse state, the collapsedProjectGroups preference that persisted it, the show-more paging, and the sort/group filter menu entries that the flat list deliberately ignores. That machinery is gone with it, along with homeListItems.ts, which nothing but its own test still referenced. buildHomeThreadGroups stays; the empty state still asks it whether any project group matched. This does remove a shipped toggle, so devices that opted into the grouped list get the flat one after upgrading.
Four compatibility shims with no remaining production callers: - persistence/Layers/ProviderSessionRuntime.ts re-exported one layer under an old name for the integration harness, which now imports the real module. - resolveLegacyProviderStatusCachePath had no callers at all. - ProviderAdapterRegistry.listProviders was reachable only from tests and the test mock; listInstances covers it. - TextGenerationShape aliased TextGeneration["Service"]; the two callers now spell that out. ProviderRegistry.refresh keeps its deprecation marker: its call sites are hard to separate from the identically named snapshot field, so retiring it wants its own pass.
.repos/ held two upstream repositories as committed git subtrees: 12,961 files and 126MB of working tree, most of it material no one here reads — alchemy-effect alone carried 14MB of images, 9MB of vendored PR screenshots, and its docs website. Every clone and every worktree paid for all of it. They are now gitignored and fetched on demand. sync-reference-repos does a shallow single-branch clone at the pinned ref, or a shallow fetch and detached checkout when the checkout already exists. Both repos land in about three seconds each. CI never had these files: every workflow already sparse-checked-out `!/.repos/`. Those exclusion patterns are now inert but left alone rather than churn the release workflows for no gain. Run `vpr sync:repos` to populate .repos/ locally. A directory left over from the subtree era has no remote to fetch from, so the sync detects the missing .git and re-clones over it.
enableLegacyTokenStreaming chose between streaming each assistant delta straight through and buffering it. Nothing rendered a switch for it, so the only way to turn it on was editing settings by hand, and it defaulted off. Both call sites now take the buffered path unconditionally, which retires the AssistantDeliveryMode literal with them. The two tests that set the flag covered a mode that no longer exists. The `streaming` field on assistant message payloads is unrelated and stays: it marks a message as still arriving, and it is a persisted event field.
Plan mode was the last thing in the Legacy settings section: a flag that restored the composer's Build/Plan toggle, the /plan and /default slash commands, and the opencode "plan" agent. It defaulted off, and the off-path already forced every thread to "default", so removing the flag just makes that path unconditional. Mobile carried a device-local mirror of it and a Build/Plan control in the new-task composer. With plan mode gone the whole Legacy section is empty, so it goes too. Kept deliberately: - ProviderInteractionMode stays "default" | "plan". It is persisted on threads and carried by thread.turn.start, so the event log still has to decode it. Threads stored in plan mode resolve to "default" like every other thread, and the next send writes that back. - PlanAgentSelectionHeal stays and now runs unconditionally. The pickers no longer offer the opencode "plan" agent, but a selection stored before this would still dispatch, so it still needs healing. - Providers keep reporting showInteractionModeToggle. No client reads it now, but it is an optional wire field and stripping it would churn all five adapters for nothing. Also drops the enableLegacyTokenStreaming settings key here rather than in the commit before it: both keys live in these two files and splitting the hunks was not worth the risk.
Two settings did nothing at all. sidebarThreadPreviewCount was read only by LegacySidebar, so removing that sidebar orphaned it; nothing has consumed dismissedProviderUpdateNotificationKeys for as long as the ledger goes back. Both still rendered in the settings summary and reset list. Appearance chrome, all reachable only from Settings and all defaulting to values the stylesheet already hardcodes: - glassOpacity and appearanceContrast were sliders over CSS variables whose index.css defaults match the schema defaults exactly, so dropping the sync renders identically. - fontSmoothing is now always on, which is what the default already did. - The composer and terminal font pickers are gone. The composer already fell back to the sans preference and the terminal to the code preference, so those two surfaces keep the fonts they had; each keeps its own size, now through a size-only row. Confirmation prompts follow reversibility instead of a preference. Deleting a thread always asks, since it clears history for good. Archiving and unpinning never do, because both are one click to undo. confirmQuit stays a real preference: quitting is not reversible and costs a relaunch. Dropping a client-settings key is safe for stored settings; decoding already discards keys it does not recognise.
git diff --numstat prints a line per changed file, which overruns execFileSync's 1MB default once a PR touches enough of them. The job then dies with a bare ENOBUFS that reads like an infrastructure fault rather than "this diff is large". Found by this PR: deleting the vendored .repos/ subtrees changes 12,961 files, and the numstat output is about 1MB on its own.
This was referenced Aug 29, 2026
This was referenced Sep 5, 2026
richardsolomou
added a commit
that referenced
this pull request
Sep 5, 2026
* fix(antigravity): keep subagent batches active after launch (#9579) (cherry picked from commit 2675e3c) * chore(upstream): record aligned changes through 2675e3c * fix(mobile): render workspace images in markdown file previews (#8769) (cherry picked from commit 09b81a3) * chore(upstream): record the markdown image module move * fix(usage): deduplicate CLI proxy subscription accounts (#9584) (cherry picked from commit b34ff8f) * fix(web): bound disconnected send toasts (#9592) Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit 07891e9) * chore(upstream): record aligned changes through 07891e9 * fix(desktop): restore panel titlebar interactions (#9591) Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit 5783280) * chore(upstream): record the desktop titlebar interaction fix * fix(connect): refresh authorization without disconnecting (#9582) Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit 39abb9d) * fix(web): show context meter in compact composer (#9430) (cherry picked from commit f559fe0) * chore(upstream): record aligned changes through f559fe0 * fix(pull-requests): refresh data after thread turns (#9496) Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit 5cc369b) * chore(upstream): record the pull request refresh adaptation * fix(web): render draft PRs in gray (#9537) (cherry picked from commit caab2fd) * chore(upstream): record the draft pull request colour * docs(upstream): rebase onto a squash-merged parent instead of merging main Squashing the parent sync branch moves the merge base behind its commits, so main and the stacked branch both look like they added the same code and git duplicates it without reporting a conflict. * refactor(web): move usage provider controls to settings (#9599) (cherry picked from commit f1e90e3) * chore(upstream): record the usage provider settings move * docs(upstream): take upstream's version when it duplicates something we built Carrying two implementations of one feature costs the maintenance and still conflicts on every future upstream edit to their copy. * refactor(web): drop the unused advanced-section locals The provider Advanced section renders unconditionally, so advancedVisible, setAdvancedOpen and searchTargetId had no readers left. * fix: show idle subagent batches without completion marks (#9616) (cherry picked from commit 00f8b7c) * chore(upstream): record aligned changes through 00f8b7c * fix(web): group image views like other tool calls (#9597) Co-authored-by: Claude Code <noreply@anthropic.com> (cherry picked from commit 61a91b6) * chore(upstream): record the shared runtime instructions convergence * fix: preserve tool icons on failed calls (#9606) (cherry picked from commit c3b8825) * chore(upstream): record the failed tool icon tint * fix(connect): diagnose incomplete headless server setup (#9602) (cherry picked from commit 99e3b72) * chore(upstream): record the relay diagnostic adaptation * fix(web): keep command palette above composer menus (#9613) (cherry picked from commit 4cc800c) * fix(web): snooze menu no longer overlaps thread details (#9601) (cherry picked from commit 93c3ab4) * chore(upstream): record aligned changes through 93c3ab4 * fix(web): match composer pull request state icons (#9375) (cherry picked from commit 7062315) * chore(upstream): record the pull request icon states * fix(server): load OpenCode workspace skills via SDK to avoid 64KB CLI pipe truncation (#9585) (cherry picked from commit 2152d44) * fix(web): mute sidebar branch name to match worktree icon (#9622) Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit ec3ec6f) * fix(web,mobile): fold context compaction under settled turn folds (#9623) Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> (cherry picked from commit 5f878d2) * feat(mobile): make chat text selectable on Android (#8779) Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> (cherry picked from commit 09d13de) * fix(web): toggle a single stashed prompt with Cmd+S (#9644) Cmd+S opened the stash menu even when the composer was empty and only one prompt was stashed. It now restores that prompt directly, so repeated presses toggle between the draft and stash. Multiple entries and images that are still saving open the menu. The stash badge still opens the menu. Validation: 94 focused stash, shortcut, and attachment tests pass. Web typecheck and formatting pass. Targeted lint has no new warnings or errors. Browser checks were skipped at Theo's request. Original implementation by Theo Browne. No code changes were needed during the takeover audit. Audited with GPT-6 Astra (preview) in Codex. (cherry picked from commit 14bf3f6) * fix(server): prevent duplicate desktop clients after restart Replace stale local desktop sessions in one transaction. Preserve paired clients and browser sessions, and keep the previous credential valid if replacement fails. Closes pingdotgg/t3code#6283. Original implementation by seeb1337. Reviewed and verified with GPT-6 Astra (preview) in Codex. Co-authored-by: seeb1337 <63622047+seeb1337@users.noreply.github.com> Co-authored-by: Theo Browne <me@t3.gg> (cherry picked from commit eb77683) * fix(web): resume Antigravity threads without repeated sign-in (#9647) Allow Antigravity threads to resume while saved Google sign-in is unchecked after a server restart. Keep confirmed authentication failures and installation errors visible. Validated with 136 focused tests, web typecheck, targeted lint, and CI. Browser verification was omitted at the maintainer's request. Created with GPT-6 Astra (preview) in Codex. (cherry picked from commit d487dfb) * feat(mobile): paste the phone clipboard into the terminal (#9199) Co-authored-by: Jake Leventhal <jakeleventhal@me.com> Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> (cherry picked from commit d5b9410) * feat(web): show which sidebar threads hold an unsent draft (#9658) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit f034732) * chore(upstream): record aligned changes through f034732 * fix(server): unblock OpenCode approvals and stop (#9653) OpenCode could show an Approval badge with no controls, appear stuck on TodoWrite, and keep showing a running turn after Stop. - Show every permission, including old saved requests. Keep failed replies retryable and close completed requests even when reply events are lost. - Keep OpenCode output pipes drained and automatic replies out of the event loop. Handle disconnects, reconnects, and confirmed stops without stale requests or running states. - Show native task progress and command results. Do not treat TodoWrite or approval history as file edits or executed commands. - Ignore late aborts and task updates after a turn finishes. Fixes #4795 Fixes #7113 Fixes #5760 Created with GPT-6 Astra (preview) in Codex. Reviewed and merged with Claude Fable 5.1 in Claude Code. (cherry picked from commit 01f3e50) * test(server): adapt the OpenCode abort tests to buffered delivery The legacy token-streaming setting these parameterised over is upstream's Legacy features flag, which this fork does not carry. * chore(upstream): record the OpenCode approval unblock * fix(desktop): quit immediately on a second shortcut press (#9657) (cherry picked from commit caa8a0d) * chore(upstream): record the desktop quit shortcut * fix(server): update Claude Agent SDK to 0.3.260 (#9135) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 560afff) * chore(upstream): record aligned changes through 560afff * perf(server): stop loading message bodies for thread summaries (#9662) (cherry picked from commit 8ac5462) * chore(upstream): record the thread summary query change * docs(upstream): reinstall before a mid-round typecheck after a manifest change * perf(web): speed up terminal snapshots (#9663) (cherry picked from commit cccd7e3) * fix(web): show machine icons in the environment picker (#9668) (cherry picked from commit 082cab2) * chore(upstream): record aligned changes through 082cab2 * perf(mobile): bound diff syntax highlighting work (#9673) (cherry picked from commit 3b6be3e) * chore(upstream): record the bounded diff highlighting * perf(web): keep Markdown mounted during streaming (#9677) (cherry picked from commit 887ece3) * chore(upstream): record the markdown streaming change * chore(upstream): register the legacy mobile list paths as removed #23 deleted the legacy home list and its presentation helpers, so upstream edits to them have nothing to land on here. * chore(upstream): record the marketing image skip * perf(server): cache and stream static web assets (#9669) (cherry picked from commit 27e6cc2) * perf(server): batch projector cursor writes (#9671) (cherry picked from commit 2263e13) * perf(server): stop retaining unused OpenCode tool history (#9684) (cherry picked from commit f2e3764) * chore(upstream): record aligned changes through f2e3764 * perf(mobile): reuse chat feed rows during streaming (#9688) (cherry picked from commit 44dc8ae) * chore(upstream): record the chat feed row reuse * perf(server): omit repeated OpenCode progress logs (#9689) (cherry picked from commit ec8b211) * perf(clients): avoid waiting to read cached relay tokens (#9691) (cherry picked from commit 2460649) * chore(upstream): record aligned changes through 2460649 * perf(mobile): reuse diff rows during comment edits (#9693) (cherry picked from commit 777f5bb) * chore(upstream): record the diff row reuse * perf(web): defer composer draft serialization (#9695) Defer the draft walk and JSON serialization until the storage write flushes. Preserve hydration, migrations, attachment verification, and final flushes. Continues the web portion of [#9049](pingdotgg/t3code#9049). The mobile storage migration remains separate. Created with GPT-6 Astra (preview) in Codex. Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit dab5f6e) * chore(upstream): record aligned changes through dab5f6e * fix(upstream): rebrand relay client ids without the product stem RelayPublicClientId spells them ras-mobile and ras-web, so the catch-all kebab rule was producing ids the schema rejects. * test(client-runtime): use a managed endpoint kind the schema accepts #54 replaced managed Cloudflare tunnels with the RAS relay, so cloudflare_tunnel is no longer in RelayManagedEndpointProviderKind. * fix(web): move the chat pane store onto the deferred storage createDebouncedStorage is gone; the pane layout now serializes at flush time like composer drafts, so a no-op set no longer stringifies the layout. --------- Co-authored-by: Theo Browne <me@t3.gg> Co-authored-by: Dara Adedeji <76637177+SunkenInTime@users.noreply.github.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: maria <maria@kuuro.net> Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com> Co-authored-by: Guilherme Vieira <46866023+GuilhermeVieiraDev@users.noreply.github.com> Co-authored-by: Exotic <118054752+extoci@users.noreply.github.com> Co-authored-by: Claude Code <noreply@anthropic.com> Co-authored-by: Guillermo Casanova <75276669+Gigioxx@users.noreply.github.com> Co-authored-by: Rakshith Bhat <88523594+RakshithBhat03@users.noreply.github.com> Co-authored-by: oliver <97427849+flamboh@users.noreply.github.com> Co-authored-by: Barry <43803274+BarryHenryJr@users.noreply.github.com> Co-authored-by: seeb1337 <63622047+seeb1337@users.noreply.github.com> Co-authored-by: Lars Nieuwenhuis <35393046+lnieuwenhuis@users.noreply.github.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
Nine commits, each self-contained. Reviewing commit by commit is much easier than reading the squashed diff.
Dead code:
6f824244adeletes twelve source files with no importer anywhere in the repo, plus.macroscope/(upstream's review bot, which does not run here) andscripts/announce-connect-ga.ts(mails a GA announcement to a private-beta waitlist that RAS Code never ran).922267b42deletes four more that the removals above orphaned.56036eec6drops four@deprecatedshims with no production callers.Legacy features, all opt-in and off by default:
ecf098a73removesLegacySidebar.tsx, a second 3.7k-line sidebar besideSidebar.tsx.505ce3bb7removes mobile's legacy grouped thread list, leaving the flat list that was already the default.dda31e7f0removesenableLegacyTokenStreaming, which chose between streaming each assistant delta straight through and buffering it.d7bca5a19removes plan mode: the composer's Build/Plan toggle, the/planand/defaultslash commands, and the opencode "plan" agent. This empties mobile's Legacy settings section, so that goes too.Options that were not earning their place (
38af8a3c9):sidebarThreadPreviewCountanddismissedProviderUpdateNotificationKeysdid nothing at all. The first was read only byLegacySidebar, so removing that sidebar orphaned it; the second has no consumer as far back as the history goes. Both still appeared in the settings summary and reset list.glassOpacityandappearanceContrastwere sliders over CSS variables whoseindex.cssdefaults match the schema defaults exactly.fontSmoothingis now always on, which is what its default already did.confirmQuitstays a real preference, since quitting is not reversible and costs a relaunch.Build:
3e85d6c31stops vendoring.repos/and fetches it on demand.Excluding
.repos/, that is 93 files and about 10k lines out.Four things kept on purpose:
ProviderInteractionModestays"default" | "plan". It is persisted on threads and carried bythread.turn.start, so the event log still has to decode it. Threads stored in plan mode resolve to"default"like any other, and the next send writes that back.PlanAgentSelectionHealstays and now runs unconditionally. The pickers no longer offer the opencode "plan" agent, but a selection stored before this would still dispatch.showInteractionModeToggle, andProviderRegistry.refreshkeeps its deprecation marker. Both are inert now, but stripping them churns the five provider adapters, which is where upstream changes land most.providersstruct inpackages/contracts/src/settings.tsis labelled legacy but is still the source of truth mid-migration, and the flat fields above it (automaticGitFetchIntervaland friends) are back-compat for old clients talking to a new server. Neither is a feature.Why
This is a fork that cherry-picks
t3code/mainregularly, so the cost of keeping something is not its line count, it is how often upstream touches it. I checked that for every candidate and it drove what went in.The dead files are dead upstream too, and most have not been touched since February to June, so deleting them costs close to nothing at pick time. Two of them,
ThreadTerminalPanel.tsxandGlassSafeAreaView.tsx, were last touched by the deferred Uniwind refactor (#7327), so removing them now shrinks that pick's surface.The legacy sidebar was the opposite: upstream changed it as recently as 2026-08-28, so every sidebar and composer pick had to be applied twice. Nothing rendered a toggle for it either. The "Settings → General → Legacy features" section that two code comments pointed at does not exist, so the only way in was hand-editing a settings blob. Legacy token streaming was the same shape.
Plan mode and mobile's grouped list are the two that did have real toggles, and both kept a lot alive behind them. The grouped list needed per-group collapse state, the
collapsedProjectGroupspreference, show-more paging, and sort/group menu entries the flat list ignores. Plan mode reached from the contracts schema through the composer, the slash menu, the traits pickers, and the model capability filter.On the settings cull: every option is a permanent tax on the settings page, the reset path, the search index, and every client that has to render it. The ones removed here were either provably inert or duplicated a decision the app can just make. Dropping a client-settings key is safe for stored settings; decoding already discards keys it does not recognise.
.repos/was 12,961 files and 126MB of working tree held as committed git subtrees, most of it material nobody reads.alchemy-effectalone carried 14MB of images, 9MB of vendored PR screenshots, and its docs website. Every clone and every worktree paid for all of it. CI never did: every workflow already sparse-checked-out!/.repos/.Run
vpr sync:reposto populate.repos/locally. A directory left over from the subtree era has no remote to fetch from, so the sync notices the missing.gitand re-clones over it.UI Changes
The default UI does not change. Every removed surface was off by default, and I confirmed in a running app that the four CSS variables behind the removed appearance sliders resolve to exactly the values those settings defaulted to (
--glass-opacity: 80%,--appearance-contrast-base: 100%, both boosts0%).What genuinely goes away, for people who had opted in or gone looking:
/planand/defaultcommands. Threads sitting in plan mode move to default on their next send.Checklist
This PR is small and focused
It is not small. You asked for one PR covering the whole cleanup. The nine commits are each one concern and are meant to be read separately.
I explained what changed and why
I included before/after screenshots for any UI changes
N/A, covered above: the default UI is unchanged and I verified the appearance variables directly.
I included a video for animation/interaction changes
N/A, no motion or interaction changes.
How did you test this code?
Typecheck and lint clean on every package touched. Full suites: web 3059, mobile 769, contracts 292, desktop 617, shared 388, server 3041.
Two tests needed thought rather than deletion, because stripping a flag changed what they assert:
composerProviderState.test.tsxusedagent: "plan"to check that non-effort selections survive dispatch. With the plan agent always filtered it now heals tobuild, so I kept the subject and moved the fixture to a different non-default selection. Its two siblings already cover agent filtering directly.composerSlashCommandSearch.test.tsused/defaultto check that an exact provider match outranks a description match, relying on "ui" appearing inside "build" in its description. I moved it to/modelwith a search term that keeps the same premise.Ran the real web app against a copy of production-shaped data and drove it:
--font-size-promptto18pxwhen changed.Ran the mobile app on an iOS 26 simulator after a clean native rebuild (the installed dev client predated the Expo SDK 57 bump and reported a React Native version mismatch, which is unrelated to this branch):
For
.repos/I ran the new sync against the real remotes rather than trusting the unit tests: clone, re-run onto the fetch path, both repos, each landing in about three seconds at the right pinned tag witheffect-smol/LLMS.mdpresent. The new stale-directory test was checked by perturbingremoveExistingto confirm it fails for the intended reason.One pre-existing failure shows up locally and is not from this branch:
apps/server/src/entrypoint.test.ts(symlink resolution). I touched neither it nor its dependencies, it keys off host platform, and CI is green ona94b40cb, the base for this branch.