chore(v2): merge main into the V2 branch (48 commits) - #13800
Merged
juliusmarminge merged 80 commits intoSep 26, 2026
Merged
Conversation
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
The Linux release build now also makes a .deb in the same electron-builder run as the AppImage, and the release publishes it. electron-builder lists it in latest-linux.yml and writes resources/package-type into it, so the app updates a .deb install through electron-updater, which installs the new .deb with dpkg. The desktop updater now allows that path. The .deb uses xz in threaded mode (XZ_DEFAULTS=-T0): 113 MB in place of 141 MB with gzip. The Linux arm64 release job moves to a 16-vCPU Blacksmith arm64 runner. The download page, README, install guide, and release docs list the .deb. Based on community work in #4071, #5139, #4900, and #4887. Co-authored-by: chukfinley <chuk@chuk.dev> Co-authored-by: Primož Ajdišek <bigpod@bigpod.si> Co-authored-by: benthecarman <benthecarman@live.com> Co-authored-by: NaveDanan <nave0712@gmail.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…13590) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…#13585) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Yash Singh <saiansh2525@gmail.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
…rotocol variables (#13492) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…and WSL backends (#13641) Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…equests (#13704) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ents, and idle polls (#13756) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g into memory (#13763) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ates per comparison (#13759) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…3761) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…le (#13765) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…13767) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…per (#13774) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…13807) Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…th failed repacks (#13812) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merges origin/main (95030dc), the 18 commits after a21b42c. Conflict resolutions that change V2 code: - AgentAwarenessRelay: keep V2's publish worker and drain, add main's unlinked backoff and requestCatchUp (cloud/http now wakes it). Main's catch-up tests are rewritten against V2's relay harness. - server.ts: keep V2's MCP route wiring, add main's untracedRequestsLayer last. - Sidebar: V2's sortSettledThreadsForSidebar is dropped for main's shared sortSettledThreads (client-runtime, same resolver); its tests moved there and use V2's latestRun. - #13767 cache encode shortcut: not taken. It relies on V1 shells being in encoded form; V2 shells hold DateTime values and V2 already encodes cooperatively (mobile shell-cache-encoding, #12117). Main's IndexedDB "abort" listener fix is kept. - #13764 queued sends: main's client-side QueuedMessageSender and queuedMessageStore stay deleted; V2 queues runs on the server (Orchestrator startNextQueuedRun), which already drains unopened threads. - #13765 / #13756: V1 ProjectionSnapshotQuery and ProjectionPipeline keep V2's versions except main's skip of empty attachment-cleanup spans. - Docs: composer.md keeps V2's queue text; keybindings.md adds usagePageOpen to V2's list. - Deleted-in-V2 V1 files that main modified stay deleted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…the binding order Main's keybindings settings rank the Usage page commands by the page's own order but left usage.open unranked. An unranked command fell back to an alphabetical compare, so the comparator was inconsistent and the list order depended on the input order. With V2's extra default bindings (threadPanel.toggle, composer.sendAlternate, ...) the settings list put Open between Tokens and Limits, and main's own test failed on this branch. usage.open now ranks first, and the test checks both input orders. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…threads that can still settle Main's periodic discovery and settlement sweeps stopped reading settled threads. V2's settlement sweep already reads candidates only (getSettlementCandidates filters settled, pinned, archived, and busy threads in SQL), but V2's PR discovery ran a full getShellSnapshot every minute: every thread, active and archived, settled or not, with every thread's run, item, and session subqueries. Discovery then dropped archived and settled threads unless they were in backfill. getShellSnapshot takes an `unsettledOnly` option (SQL and memory store), and the periodic discovery sweep reads active, unsettled threads unless a backfill pass is pending, as on main. A pending backfill entry for a thread with no branch is cleared so it cannot keep every pass on the full read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
OpenCode generates a session title from the first prompt only when session.create leaves the title unset (SessionPrompt.ensureTitle). Main stopped forwarding prompt-seeded titles from the V1 ProviderCommandReactor, which V2 deleted. V2's OpenCode adapter sent a placeholder title, "T3 Code <threadId>", on every session.create, so every V2 OpenCode session in OpenCode's own UI and history was named after an id. session.create no longer sends a title. Main also forwards a title the user renamed by hand. V2 has no title-provenance field on the thread and never sent the thread title, so that part is left out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…path Main's #13339 changed V1's Antigravity adapter to pass unsupported files by path, and the merge brought its doc text, which describes V1's native PDF, text, and audio limits. V2's Antigravity runs through AcpAdapterV2, which embeds only images and passes every other attachment as a saved path (AttachmentPrompt.providerMessageTextWithAttachmentPaths), with reads confined by AntigravityClientFiles. The V1 support code merged but has no V2 caller. The provider page now describes V2's behavior. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| <span className="flex min-w-0 items-center gap-2 text-sm text-foreground"> | ||
| <span | ||
| aria-hidden | ||
| className="size-2 shrink-0 rounded-full" |
Contributor
There was a problem hiding this comment.
Tailwind ownership: this Cursor swatch uses a static inline color. Please put bg-[#8b8b8b] on the owning element instead.
Suggested change
| className="size-2 shrink-0 rounded-full" | |
| className="size-2 shrink-0 rounded-full bg-[#8b8b8b]" |
Posted via Macroscope — UI Consistency
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
juliusmarminge
added a commit
that referenced
this pull request
Sep 26, 2026
#13800 brought main up to 95030dc into V2, but its squash merge dropped main as a parent, so GitHub still diffed #2829 against the old merge base and reported conflicts. This records 95030dc as merged; the tree is unchanged because #13800 already contains those commits and their ports. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Merges
origin/mainat a21b42cec4, 48 commits past the merge base a107f8a079, into the V2 branch. It keeps main's fixes, carries main's performance work over to V2's replacement code, and keeps everything V2 added.Merge, not rebase. The request was a rebase. This PR is one merge commit plus follow-up port commits. A rebase would rewrite all 715 V2 commits, break every open stacked PR on
t3code/codex-turn-mapping, and need a force-push to a shared branch. Nothing here needs a real rebase.Commits:
Each port commit covers one main PR, so each can be reverted on its own.
Refresh (second batch). The branch now also includes:
origin/mainat 95030dc674, 18 commits after a21b42c, in 8119814a66.Pushes were fast-forward only. #13742 (mobile PR icon, one file) landed on main after the second merge and is not included; it belongs in the next merge.
Decisions
First batch (main a107f8a..a21b42c)
Legend: A = ACCEPT, P = PORT, S = SUPERSEDED, D = NEEDS-DISCUSSION. Paths are relative to
apps/server/src/unless they start withapps/orpackages/.compileCache.tsis new. TheflushCompileCachecall conflicted with V2's imports inserverRuntimeStartup.tsand is kept.effectiveEnvModeOverrideprop. The merge wiresenvModethroughChatView→ThreadDetailsPanel→BranchToolbarand applies main's label and icon rules to V2's env-mode selector markup.t3 appsurvives a second desktop quitusage/*; not touched by V2.usageSummaryrefresh trigger.packages/shared/nodeSqliteClient; applies to V2's SQLite too.ThreadComposer.tsx: V2'siconUrlmoved onto main'srenderIcon(size)API.TerminalManager.closeIdleand the setup-script cleanup merged cleanly (shared code). The settle trigger lived in V1ProviderCommandReactor, which V2 deleted, and V2's settle only detached the provider session.ThreadSettlementServiceV2now handlesthread.settled: it re-reads the thread and callscloseIdleonly if the thread is still settled.provider/cursorKeychainToken.ts(see below).vcs/GitVcsDriverCore; shared by V2.SidebarProviderStack. V2's one-off.provider-stack-badge-text { font-size: 7px }is replaced with main's newtext-5xstoken (same 7px), and the one-off class is removed.otlpServiceNamefield from V2 testkits (CodexAdapterV2.testkit.ts,CursorAdapterV2.testkit.ts,testkit/ProviderReplayHarness.ts,cli/project.test.ts).orchestration/projector.ts, which still backs V1OrchestrationEngine: V2'sruntimeLayer.ts:86still wires it forProjectServicecommands. V2's own read side has no in-memory list of all threads.ProjectionStoreV2.applywrites one row per event, and shell streams re-read only changed threads (orchestration-v2/ProjectionStore.tsgetThreadShell). The client still has a cheaper version of this cost (memory notes below).provider/Layers/ClaudeAdapter.tsis deleted in V2.ClaudeAdapterV2never collected per-turn SDK messages:readThreadSnapshotfails with "does not implement snapshots" (orchestration-v2/Adapters/ClaudeAdapterV2.ts:6832), and there is noturns[].itemsstate.processRunner; shared.t3 triagepoints at log files that existpersistence/Layers/Sqlite.ts; applies to the V2 database.Sqlite.test.tspasses.bin.tsintobinCli.ts, sotraceCommandwas left unregistered (knip flagged it). Registered inbinCli.ts:78.PullRequestSyncReactorcalledOrchestratorV2.getShellSnapshot()every minute. That call builds every thread's shell, archived ones included, then everything unlinked was dropped. AddedProjectionStoreV2.getThreadsWithPullRequests(orchestration-v2/ProjectionStore.ts:5046): oneSELECTwithjson_array_length(payload_json,'$.pullRequests') > 0, plus a matching in-memory store implementation. Main'slistThreadsWithPullRequestson V1ProjectionSnapshotQuerywas not taken: it queriesprojection_thread_pull_requests, which V2 never writes (links live in the V2 thread payload).HeapSnapshot.layeris wired into V2'sserver.ts. Useful for the V2 memory work below.ProviderService.tsis deleted in V2.ProviderSessionManagerV2.shutdown(orchestration-v2/ProviderSessionManager.ts:1515) iterates only live in-memory sessions; stopped rows are never touched.ProjectionSnapshotQuery(still used for projects and some reads). V2'sProjectionStore.getShellSnapshotdecodes each payload once and builds plain objects (shellFromState); there is no whole-snapshot re-decode.client-runtimeHTTP snapshot timeouts; the V2 client uses these loaders.const serverThread = useThreadShell(threadRef)(apps/web/src/components/ChatView.tsx:942). Main's active-draweruseThreadfallback exists for archived V1 threads without a shell. V2 needs only the worktree path and project, so V2's side is kept.getSettlementCandidates(threadId?)now filters in SQL (ProjectionStore.ts:4944), and a sweep with no candidates stops early.ThreadPullRequestServiceV2readsgetThreadEventSequencethengetThreadShellfor one thread (ThreadPullRequestService.ts:126), and a one-thread read only clears that thread's pending backfill (as on main).EventLoopMonitor.layeris wired into V2'sApplicationObservabilityLive.ws.tsmerged cleanly. V2'sThreadPullRequestServiceresolved identities withoutrefresh, so after a turn it could miss a newly added remote for up to 15 minutes. Discovery requests already markedrefresh: truenow pass it through to the resolver.data-chat-width, and minimap gutter logic merged; the minimap tests are ported onto V2's test. V2 sizes the lane with--chat-content-max-widthrather than main's--chat-max-width, so the setting did nothing until the port. Wide and Full now override V2's token. D: V2's comfortable width stays 46rem, not main's 48rem.provider/opencodeRuntime.tsis shared withOpenCodeAdapterV2.ReplayMarkers.layeris added to V2'sRuntimeCoreDependenciesBaseLive(server.ts:525) because main'sReactorLayerLivechain doesn't exist in V2.Second batch (main a21b42c..95030dc)
vp ifrom main's lockfile, keeping V2's deps (@cursor/sdk,@napi-rs/keyring).Sidebar.tsx.ProviderCommandReactoris deleted. V2'sOpenCodeAdapterV2sent a placeholdertitle: "T3 Code <threadId>"on everysession.create, which stops OpenCode from generating a title. It now sends no title. D: main also forwards a hand-renamed title; V2 has no title-provenance field and never sent the thread title, so that part is left out.AntigravityAdapteris deleted. The sharedbuildAntigravityPromptmerged, but V2 has no production caller for it. V2's Antigravity runs throughAcpAdapterV2, which embeds only images and passes every other file as a saved path (AttachmentPrompt.providerMessageTextWithAttachmentPaths). Reads are confined byAntigravityClientFiles(#13613). Main's doc text described V1's native PDF/text/audio limits, soproviders-antigravity.mdnow describes V2.usagePageOpenadded to V2's keybindings doc list. Main leftusage.openunranked in the settings sort, which made the comparator inconsistent. With V2's extra default bindings, main's own test failed.usage.opennow ranks first, and the test checks both input orders.processRunner,shell,GitVcsDriverCoreandPortScannerchanges merged. Main's skip of the empty attachment-cleanup span is kept in V1ProjectionPipeline. V2'sProjectionStoreV2.applyis a plain untracedEffect.gen, so it writes no per-event span.diagnostics/TraceDiagnosticsandcli/traceare shared with V2.sortSettledThreads(client-runtime) and precomputed project sort apply to V2. V2's duplicatesortSettledThreadsForSidebaris dropped for main's shared one (same resolver). Its tests now live inclient-runtime/threadSort.test.ts, converted to V2'slatestRun.untracedRequestsLayeris added last in V2'smakeRoutesLayer, after V2's MCP wiring.getSettlementCandidatesalready filters settled, pinned, archived and busy threads in SQL (ProjectionStore.ts, #13691 port). PR discovery was not: its minutely sweep read every thread, active and archived.getShellSnapshotgainsunsettledOnly(SQL and memory store), and discovery reads active, unsettled threads unless backfill is pending, as on main.DateTimevalues, so that shortcut would write the wrong format. V2 encodes through its V2 cache schema, and mobile already yields during large saves (apps/mobile/src/connection/shell-cache-encoding.ts, #12117). Main's IndexedDBabortlistener fix is kept. D: the V2 web encoder still does not yield (see memory notes).drain, and adds main's unlinked backoff (5s → 60s) andrequestCatchUp, whichcloud/httpnow calls. Main's three catch-up tests are rewritten against V2's relay harness. Reaper: V1ProviderSessionReaperis deleted, and V2 has no polling reaper; idle release is one timer per live session (ProviderSessionManager.tsscheduleIdleReleaseInternal). The repository's newexcludeStoppedoption merged; V2's onlylist()caller (AgentSessionImporter) needs stopped rows.queuedMessageStore, f7a764c8ee). Queued messages are server runs, andOrchestrator.startNextQueuedRunstarts the next queued run when a run ends, whether or not any client has the thread open.resumeQueuedRunsalso recovers them after restart. Main'sQueuedMessageSender,sendQueuedMessageand root mount are not taken.vcs/GitVcsDriverCoreis shared with V2.Migrations
Second batch: main still has no new migration (latest
054), and its only contract change iskeybindings.ts(new commands andusagePageOpen, all additive). Both upgrade paths are unchanged, and the migration and import tests still pass.At merge time, and rechecked against
origin/mainat 2679d279ce: main has no new migration files. Its latest is still054_ProjectionThreadsAutoSettleDisabledAt, and V2 adds055_OrchestrationV2and056_RemoveRedundantProjectionIndexes, so numbers don't collide. No migration was added here.LegacyV1ThreadImporterandLegacyV1Cutoversee the same schema they were written against. Main'sSqlite.tschange is a WAL checkpoint after large writes, which only helps the import. The 055/056 migration tests and the LegacyV1Cutover/Importer tests pass.getThreadsWithPullRequestsand thegetSettlementCandidatesfilter only read existing V2 columns (payload_json,deleted_at,updated_at) and need no index change.ClientSettings.chatWidthandServerSettings.cursorKeychainUsageEnabledboth have decoding defaults, so stored V2 settings still decode.usage.tsbumpsUSAGE_CONTRACT_VERSIONto 6 with added provider literals and optional fields. Usage is computed per request, not stored. Theeditor.tschange edits a static list only.V2 changes altered during conflict resolution
bin.ts: kept V2's thin entry. Main's command list edit went intobinCli.ts(port commit).server.ts: kept V2's layer graph and addedReplayMarkers.layer. The PR sync worker now also getsProjectionStoreV2.layer(from the perf(server): pull request sync reads only threads with linked pull requests #13704 port).ProjectionSnapshotQuery(still in V2): dropped the whole-snapshot decode (perf(server): build the thread list snapshot without decoding it twice #13693). Did not addlistThreadsWithPullRequests.CursorDriver.ts/cursorUsageLimits.ts: kept V2's SDK-based driver and passed main'scursorKeychainUsageEnabledthrough. Main'sprovider/cursorCredentialStore.tsdiffers only by case from V2'sprovider/CursorCredentialStore.ts:tscfails with TS1149, and it would break on macOS. It is renamed toprovider/cursorKeychainToken.ts, with its test and imports updated. Main's Cursor usage tests moved from the V1-shapedCursorProvider.test.tsinto V2'scursorUsageLimits.test.ts, with labels updated to main's "Overall / Cursor Models / Other Models".apps/web/.../usage/usageProviders.ts: kept V2'sdriverKind-based presentation instead of main'smarkicons, and added cursor, opencode and antigravity in V2's shape.packages/client-runtime/.../server.ts: kept V2'ssearchAcpRegistry. The singleusageSummaryatom now uses main'susageScanSettingsAtomtrigger.MessagesTimeline*,ChatComposer,ComposerSurface,ChatView: kept V2'schat-content-lanemarkup and dropped main'sTimelineLoadEarlierHeader, which V2 already removed. The drawer keeps V2's shell-only read.SettingsPanels.tsx: both rows kept (V2's composer-context row and main's chat-width row).scripts/lib/cli-external-packages.test.ts: the expected list now has both@cursor/sdk(V2) and@napi-rs/keyring(main).ClaudeAdapter,ProviderService,ProviderCommandReactor,ThreadSettlementReactor,ThreadPullRequestReactor, andOrchestrationEngine/ProjectionSnapshotQuery/ProviderSessionReapertests, plusbin.test.ts,server.test.ts, andintegration/OrchestrationEngineHarness.ProjectionSnapshotQuerykept V2's versions. The one auto-merged mock that gainedlistThreadsWithPullRequests(AgentSessionScanner.test.ts) had it removed.Second batch
AgentAwarenessRelay: the service has bothdrain(V2) andrequestCatchUp(main).cloud/http.teststubsdrain.server.ts:untracedRequestsLayergoes after V2's MCP route layer.Sidebar.logic.ts: V2'ssortSettledThreadsForSidebaris removed in favor of main's sharedsortSettledThreads.KeybindingsSettings.logic.ts:usage.openis ranked (port commit).OpenCodeAdapterV2: no placeholder session title (port commit).composer.mdkeeps V2's server-queue text; main's Antigravity video line merged and is true for V2.providers-antigravity.mdis rewritten for V2's path-based attachments.QueuedMessageSender,sendQueuedMessage,queuedMessageStore,encodeShellSnapshotForCacheand its test, and theunsettledOnlyplumbing on V1ProjectionSnapshotQuery(V2 has no caller for it).provider/cursorCredentialStore.ts, and batch 2 did not touch it, so V2 keeps it ascursorKeychainToken.ts.V2 memory and CPU hotspots worth a follow-up (not fixed here)
V1 engine still resident.
orchestration-v2/runtimeLayer.ts:86,305wiresOrchestrationLayerLive, whoseOrchestrationEnginehydrates a full in-memory V1 read model at boot (orchestration/Layers/OrchestrationEngine.ts:344-345) and keeps it for the process lifetime. The only user isProjectService's V1 commands. This is probably the largest fixed memory cost in V2.Unbounded event buffers.
EventSink.ts:200(live PubSub) and:626(one unbounded PubSub per event type, never removed).ProviderSessionManager.ts:1219has one unbounded queue per session subscriber. A slow consumer, such as a stalledstreamDomainEventssubscriber, buffers without limit.Adapter maps that grow per item and are cleared only on reset.
ClaudeAdapterV2.ts:2788itemOrdinalsis copied (new Map(current)) on every new item and never pruned. That is O(items) memory and O(items²) copying over a long session.CursorAdapterV2,AcpAdapterV2, andCodexAdapterV2.ts:1639planDeltas, which keeps the full plan text per item.Shell stream per streaming delta. Every V2 event, including turn-item deltas, becomes a shell event. Each busy thread then costs one heavy
getThreadShellquery per 50ms window per client. On the client, eachthread.updatedmaps the whole thread array (client-runtime/state/shellReducer.ts:7) and rebuilds the thread index (threadShell.ts:71). This is the client-side counterpart of perf(server): stop remapping every thread on each thread event #13720.Remaining full-shell reads on background paths.
relay/AgentAwarenessRelay.ts:689,CheckpointRestoreSafety.ts:28(reads the full shell, then checkpoint context for every other thread),ThreadManagementServicelistProjectThreads, and the minutely full sweeps in both settlement and PR discovery.Unbounded, non-deduplicating worker queues.
DrainableWorkerdoes not merge repeated requests, so a burst ofrun.updatedevents queues one sweep per event even after perf(server): per-thread settlement and PR checks no longer rebuild the whole thread list #13691.Small leaks.
assistantStreaming.ts:93: the per-message buffer is removed only on a final update, so interrupted streams leave it behind.CheckpointService.ts:252: one semaphore per working directory, never removed.Web shell cache encode (perf(clients): saving the thread list cache no longer freezes the UI #13767 counterpart).
apps/web/src/connection/storage.tsencodes the whole V2 shell snapshot through Schema in one go on every save. Mobile yields every 32 rows; the web path doesn't, so a large thread list can still stall a web frame on save.Please check these (riskiest calls)
ThreadSettlementServiceV2as a domain-event reaction, not as an effect in the V2 outbox. It is not replayed after a crash, which matches main's reactor. An outbox effect would need a new effect type and more machinery.cursorCredentialStore.tsis nowcursorKeychainToken.tson this branch. The next main merge will conflict on it again unless main renames it too.Second batch:
7. #13764 superseded. V2 drains queued runs on the server, so a thread nobody has open still sends. I confirmed this in code, not in a live run.
8. #13368 drops the placeholder title but does not forward hand-renamed titles.
9. #13767 not ported. The V2 web cache encode is untouched (memory note 8).
10. #13765 port. The PR discovery sweep now reads unsettled-only unless backfill is pending. A settled thread whose PR changes waits for backfill or a per-thread event, as on main.
Verification
Second batch, on head b049c24:
tsc --noEmit: server, contracts, client-runtime, effect-acp, web, mobile all report 0error TSand 0warning TS.vp run knip:check: passes.KeybindingsSettings.logic.test.ts(Usage order)ProjectionSettlement.test.ts(unsettled-only SQL/memory parity)ThreadPullRequestService.test.ts(periodic sweep is unsettled-only after backfill)OpenCodeAdapterV2.test.ts(no session title)First batch:
tsc --noEmit: server, web, mobile, client-runtime, contracts, effect-acp all report 0error TSand 0warning TS.vp run knip:check: passes.055_OrchestrationV2*.test.ts(3 files),056_RemoveRedundantProjectionIndexes.test.ts,LegacyV1Cutover.integration.test.ts,LegacyV1ThreadImporter.test.ts,Sqlite.test.tsall pass.OrchestratorReplayFixtures.integration.test.ts, 93/93 pass.ThreadSettlementService.test.ts(new settle-terminal and single-thread tests),ThreadPullRequestService.test.ts(new one-thread-read and refresh tests),PullRequestSyncReactor.test.ts(asserts no shell read),ProjectionSettlement.test.ts(new SQL/memory parity test forgetThreadsWithPullRequests),cli/trace.test.tsall pass.scripts/build-desktop-artifact.test.tshas 15 failures, and they are pre-existing. The same 15 fail with V2 HEAD's versions of the file on this machine (asar unpack under the custom TMPDIR).Model: Claude Opus 5.5 (Claude Code)
🤖 Generated with Claude Code