Repository navigation
perf(web): saving the thread list cache no longer re-encodes every thread - #19915
Merged
juliusmarminge merged 8 commits intoOct 16, 2026
Merged
Conversation
…ead on the UI thread
Contributor
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR not approvable — This production-path change replaces web shell-cache encoding with shared memoization and browser task yielding, while relocating the existing mobile encoder and adding focused tests. It also adds a file-level directive suppressing two static-analysis diagnostics, so the change requires human review. You can add or adjust custom eligibility rules. Learn more. |
Contributor
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Note Claude Opus 5.5 responding on behalf of Julius. Taking over this one. I will push follow-up commits to this branch on top of yours and merge |
…equality and row reuse The encoder moved from mobile into client-runtime, so its tests move with it. Three cases remain: output matches the schema codec byte for byte across a warm save with changed, added and archived rows; an unchanged row's encoding is reused rather than re-encoded; and the default yield is a host timer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The encoder moved from apps/mobile to packages/client-runtime, but the takeover's first pass replaced main's nine encoder tests with three new ones. Move main's `cooperative shell cache encoding` block verbatim into packages/client-runtime next to the encoder instead, keeping only the fixture it needs, and leave the mobile store tests as they are on main. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… cache Keep the encoder's zero-delay timer as the default yield so mobile keeps its behavior without passing anything, and scope the timer diagnostic suppression to the one call instead of the whole module. Correct the comment: Effect's own yield goes through setImmediate where the host has it, which on React Native is a microtask shim. On web, a MessageChannel message resumes encoding in a fresh task, so input and rendering get a turn between chunks without the 4 ms nested timer clamp or background-tab throttling. Closing the port on interrupt is enough cleanup; a closed port delivers nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pipyakas
pushed a commit
to Pipyakas/t3code
that referenced
this pull request
Oct 18, 2026
…read (pingdotgg#19915) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit e2b929f)
aorwall
added a commit
to aorwall/t3code
that referenced
this pull request
Oct 19, 2026
Merges `pingdotgg/t3code` `main` at `3962ae8586` (96 commits since `e536bfd33b`) into the fork. One merge commit; the tracker entry in `docs/fork/upstream-merge-log.md` has the full decision list. ## Conflicts (8) - **`ChatView.tsx`** (`converged`): upstream pingdotgg#19869 replaced `useCallback` with plain functions plus `useStableCallback`. I took upstream's file and re-applied each fork delta in that style: the sandbox start for scripts, the draft-thread create and host-run path in `runProjectScript`, Workspace script saves, the sandbox surface, file retargeting, the announced preview and terminal effects, the sandbox-commands banner, the PR-surface gate and the thread-fork dialog. **This file is the one to review closely.** - **`rightPanelStore.ts`** / **`FilePreviewPanel.tsx`**: the fork's `retargetFile` sits beside upstream's new `navigateFolder` and `folderTrail` (pingdotgg#15045). - **`ci.yml`**: upstream folded the `typecheck` job into `build` (pingdotgg#19633). The Moatless spec check now follows `build`'s final `Typecheck` step. - **`Sidebar.tsx`, `ProjectSettingsPanel.tsx`**: upstream's code plus the fork's additions. - **`index.html`**: kept the Moatless title. Added a `branding-shell` path-policy entry for it and `branding.ts`. - **`source-control-github/package.json`**: took upstream's new `generate` script and kept `tsc --noEmit` (the `tsc-rs` tripwire). - **`pnpm-lock.yaml`**: took upstream's copy, stripped `tsc-rs`, and re-derived it with a real install. Merge stats: 738 files landed against 736 in the upstream range. The one upstream file that didn't land is `index.html`, whose only upstream change was the title. The three extra landed files are fork docs. The fork delta is 815 files. ## Contract - Added `UnsupportedMethodError` to `orchestration.subscribeCommandOutput` and `server.getDatabaseStorage`. Both are new upstream methods Moatless doesn't dispatch. - Moatless now serves 11 more `pullRequests.*` reads (moatless pingdotgg#1161, pingdotgg#1164, pingdotgg#1169). They share `PullRequestRpcError` with methods it still refuses, so the union keeps `UnsupportedMethodError`. The 11 are declared as `pull-requests-*-shared-union` exceptions in `inventory.json`, which retire together once the rest of the family is served. ## Also in this PR `sandboxSurfaces.test.ts` had been red on `main` since `95dcaca54f` made the `pull-request` surface sandbox-independent without updating the test. The test and module doc now match the code. ## Verification Duplicate-adds, tripwires, resolution-check, unsupported-methods, lockfile, format, lint, typecheck and the production build are all green. The full test pass hit its one-hour deadline, so I ran the remaining packages one at a time. These still fail when run alone, in the same files the 2026-10-15 merge logged as sandbox failures: - `shared`: `AgentScope` - `t3`: `ServerBrowserPage`, `AcpAdapterV2` - `provider-opencode`: `OpenCodeServerLedger` - `ssh`: `tunnel.test.ts` `t3`'s `OrchestratorReplayFixtures` `claude_result_is_error` fails only because this sandbox sets `CLAUDE_CONFIG_DIR`; it passes with that unset. Every other package passes. ## Upstream features ### Usable as-is - Folder breadcrumbs navigate to parent folders (pingdotgg#15045). - Chat view, composer and sidebar no longer keep old renders alive (pingdotgg#19869, pingdotgg#19852). - Thread list cache saves without re-encoding every thread (pingdotgg#19915). - React Compiler runs natively (pingdotgg#20114). - Linked pull requests are virtualized (pingdotgg#20107). - A linked PR can be dragged into the composer as a context chip (pingdotgg#20102). - HTML renders show a skeleton and open images in the image viewer (pingdotgg#19654, pingdotgg#20036). - Model picker search lists the newest models first (pingdotgg#18494). - Wrapped split diffs stop jumping while scrolling (pingdotgg#20022). - Text selection continues under the turn minimap (pingdotgg#16748). - Sent queued messages say "from queue" (pingdotgg#19849). - Settings stay compact with many connected machines (pingdotgg#19744). - Middle-click and a setting to open PR links on GitHub (pingdotgg#19854, pingdotgg#19719). - Text generation no longer falls back to the flagship model (pingdotgg#19722). - Pending context handoff is hidden on threads with no sent message (pingdotgg#20033). - Mobile and desktop changes don't affect the fork's web client. - Not taken: the Beta branding (pingdotgg#20032). ### Unsupported in Moatless / needs implementation - **Live command output** (pingdotgg#15094): `orchestration.subscribeCommandOutput`, shown in `CommandOutputPanel.tsx` behind `capabilities.commandOutputStreaming`. Covered by the new union entry. - **Database storage notice and `t3 doctor` reclaim** (pingdotgg#19436, pingdotgg#19437): `server.getDatabaseStorage`, shown in `DatabaseStorageNotice.tsx` behind `capabilities.databaseStorage`. Covered by the new union entry. - **Delete a branch after its PR merges or closes** (pingdotgg#19257): a `pullRequests.runAction` option. The action is refused here. - **Device setup through a remote device host only** (pingdotgg#20077): behind `FEATURES.deviceHub`. ### Backend behavior to consider reproducing in Moatless - Resumed Claude subagents keep updating their own thread and pick up the parent's renamed worktree branch (pingdotgg#20061, pingdotgg#20079). - Steering no longer ends running subagents (pingdotgg#19210). - Worktrees shared by subagents are cleaned up, and orphaned ones are reported (pingdotgg#19748, pingdotgg#19749). - Superseded history is compacted in the background (pingdotgg#19435). - A run whose provider stream ends without a terminal event fails instead of hanging (pingdotgg#19131). - One malformed ACP session update no longer ends the session (pingdotgg#20015). - A dropped HTTP/2 connection no longer crashes the server (pingdotgg#18378). - PR refreshes are bounded by tracker reads (pingdotgg#19403). - Cursor threads in Auto use Cursor's Auto-review (pingdotgg#19712). - Grok health checks no longer start its updater (pingdotgg#18075). - Expanding a wide ignored folder no longer classifies every child (pingdotgg#20062). - OTLP exports name the machine and build they came from (pingdotgg#19370). Recorded in `docs/fork/gaps.md` under "Runtime fixes upstream made to its own server". 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Moatless task: https://moatless.soaplabstest.com/tasks/d6f425f2-8234-412e-8189-1c71b309c04a
Pipyakas
pushed a commit
to Pipyakas/t3code
that referenced
this pull request
Oct 19, 2026
…read (pingdotgg#19915) Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit e2b929f)
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.
Saving the thread list cache in the web client now encodes only the threads that changed. With 1,417 real threads (4.6 MB), a save after one thread changes drops from 791 ms to 11 ms of UI-thread work in Chrome, and the saved bytes are identical.
Problem
Every
saveShellin the web client ran a fullSchema.encodeEffectover every thread row, even when one row had changed. The shell cache saves every 10 seconds while threads update, so a large thread list kept the UI thread busy for most of a second each time.encodeShellSnapshotForCachehad kept this cheap before the V2 orchestrator (#2829) removed it.Change
makeStoredShellSnapshotEncoder, perf(mobile): reuse encoded rows in shell cache saves #16129) moves fromapps/mobile/src/connection/shell-cache-encoding.tstopackages/client-runtime/src/platform/shellCacheEncoding.ts, with its tests. Shell rows are immutable and kept by reference, so the encoder remembers each row's encoding and only runs the row codec for new rows.saveShelluses it and yields between chunks with aMessageChanneltask. A zero-delay timer is clamped to 4 ms after a few nested calls and throttled to about once a second in background tabs, and the shell flush also runs on disconnect.setTimeout(0)yield. Its behavior is unchanged.Schema.fromJsonString(StoredOrchestrationShellSnapshot). The web client now keeps one encoded copy of each live row, as mobile already does: about 15 MB of heap for 1,600 rows with 10 pull request links each.Scope and approval
Fixes #18926, which was triaged as an accepted regression. The triage comment asked for exactly this scope: move the encoder into client-runtime, call it from
saveShell, keep byte equality with a test like mobile's, keep mobile's yield, use a browser-friendly yield on web, and leave payload size for #18907.Verification
packages/client-runtime/src/platform/shellCacheEncoding.test.ts: byte equality, row reuse, chunked yields, invalid rows, concurrent saves, interruption and failed encodes. 9/9 pass. The mobile store tests that stay behind pass (8/8), as do webstorage.test.ts(10/10).vp run typecheckin client-runtime, web and mobile, plus targeted lint and format: clean.Original work by @bompus, taken over and finished by maintainers.
Claude Opus 5.5 and Claude Fable 5.1 in Claude Code, with review by GPT-6.1 Sol in Codex.
🤖 Generated with Claude Code