Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
244 commits
Select commit Hold shift + click to select a range
af7ec2c
perf(server): load pending migrations and cache current schemas
maria-rcks Oct 11, 2026
8dadb4b
perf(server): parallelize boot reads and streamline desktop startup
maria-rcks Oct 11, 2026
f50e02b
perf(server): avoid repeated thread and event encoding
maria-rcks Oct 11, 2026
91f17f9
fix(server): close inherited electron descriptors before startup
maria-rcks Oct 11, 2026
d3ae6b7
fix(desktop): release closed preview tab generations
maria-rcks Oct 11, 2026
fef15ac
fix(server): preserve electron-owned descriptors during cleanup
maria-rcks Oct 11, 2026
e9bb84c
perf(server): bound vcs status retention without json fingerprints
maria-rcks Oct 11, 2026
d9ead43
fix(server): retain subscribed vcs statuses until release
maria-rcks Oct 11, 2026
e3a148b
fix(server): capture baselines before provider startup
maria-rcks Oct 11, 2026
3045c12
perf(server): reuse validated indexes for warm checkpoints
maria-rcks Oct 11, 2026
5921afd
fix(server): pin cached indexes to resolved heads
maria-rcks Oct 11, 2026
ea74e42
perf(server): keep disk copies for cold checkpoint indexes
maria-rcks Oct 11, 2026
162493b
perf(client): preserve state references and write smaller caches
maria-rcks Oct 11, 2026
79cfb20
perf(threads): hydrate older history outside the initial viewport
maria-rcks Oct 11, 2026
52f269b
perf(web): reuse markdown parses and observer row measurements
maria-rcks Oct 11, 2026
9ee41d6
perf(web): render streamed tokens in the assistant row
maria-rcks Oct 11, 2026
5204ffb
perf(web): isolate sidebar row updates and viewport content
maria-rcks Oct 11, 2026
cde71b2
perf(web): skip zero displacement at drag release
maria-rcks Oct 11, 2026
a13eb0c
perf(web): scale virtual rows with interface font preferences
maria-rcks Oct 11, 2026
b0b4ee5
perf(web): defer boot codecs and measure layouts with refs
maria-rcks Oct 11, 2026
5a0c1e4
perf(bundle): remove duplicate themes and redundant dependencies
maria-rcks Oct 11, 2026
bfd3540
perf(desktop): use native fetch in the main process
maria-rcks Oct 11, 2026
5904198
chore(cursor): remove a missing keychain token entry point
maria-rcks Oct 11, 2026
9dd6545
perf(desktop): split main evaluation and defer the updater sdk
maria-rcks Oct 11, 2026
ecd490f
perf(desktop): render the cached composer without the session wait
maria-rcks Oct 11, 2026
d291118
perf(review): reuse previews until the workspace changes
maria-rcks Oct 11, 2026
35d437e
perf(web): warm file viewer assets while picking files
maria-rcks Oct 11, 2026
38bc8e2
perf(web): reuse palette search work and defer focus
maria-rcks Oct 11, 2026
3bdabb8
perf(web): defer settings surfaces and batch row mounts
maria-rcks Oct 11, 2026
b9f404b
perf(web): avoid panel layout reads and stream terminal wasm
maria-rcks Oct 11, 2026
37c86c1
fix(review): scope preview freshness to each client
maria-rcks Oct 11, 2026
907929d
test(server): the MCP credential channel test reads the runner servic…
maria-rcks Oct 11, 2026
b70737c
docs(desktop): the updater layers are wired in application.ts
maria-rcks Oct 11, 2026
655db45
test(web): the find bar canvas test passes the composer overlay as a ref
maria-rcks Oct 11, 2026
d1673ef
chore: merge t3/app-startup-performance-audit 42e2b35b29
maria-rcks Oct 11, 2026
938d5cb
perf(web): keep composer typing out of frame renders
maria-rcks Oct 11, 2026
9971059
fix(web): preserve composer traits availability
maria-rcks Oct 11, 2026
9e166f6
perf(web): reuse composer document maps for caret checks
maria-rcks Oct 11, 2026
4f11577
perf(web): composer editor re-renders skip the prompt parse
maria-rcks Oct 11, 2026
1d19597
fix(desktop): main-process requests no longer follow env proxies
maria-rcks Oct 11, 2026
56de794
fix(desktop): keep electron-store as a direct dependency
maria-rcks Oct 11, 2026
b7e6448
perf(desktop): render the cached chat view in one task
maria-rcks Oct 11, 2026
1a02c57
perf(web): long settings lists mount one row batch per frame
maria-rcks Oct 11, 2026
6ca9d57
fix(web): an expanded fold loads history only for the run the window …
maria-rcks Oct 11, 2026
86f357a
perf(web): sidebar search rows compile under the React Compiler again
maria-rcks Oct 11, 2026
33faff0
fix(web): sidebar tooltips stay open while other panes scroll
maria-rcks Oct 11, 2026
d3d5603
fix(web): tabbing onto an off-screen sidebar row focuses the row
maria-rcks Oct 11, 2026
34628a2
fix(web): palette views focus their input when they mount
maria-rcks Oct 11, 2026
1a9e2e2
fix(client-runtime): history pages keep unapplied live runs and check…
maria-rcks Oct 11, 2026
bd01667
fix(web): the first shell cache save drops rows of removed environments
maria-rcks Oct 11, 2026
4acf4f8
perf(web): license rows mount in larger batches after the first paint
maria-rcks Oct 11, 2026
20678ac
fix(web): composer caret stays after a typed @name or $name
maria-rcks Oct 11, 2026
b810132
fix(web): composer reacts to rewrites from outside the editor, not to…
maria-rcks Oct 11, 2026
7c6b340
perf(server): checkpoint index cache no longer forces full GCs
maria-rcks Oct 11, 2026
1434ddf
fix(server): a failed baseline no longer blocks every turn
maria-rcks Oct 11, 2026
9a35a6d
fix(server): review previews leave memory once the panel goes idle
maria-rcks Oct 11, 2026
0f75fe6
fix(threads): viewport snapshots keep recent turns and the open turn'…
maria-rcks Oct 11, 2026
4556dbe
perf(web): a reload past the session wait renders the cached chat vie…
maria-rcks Oct 11, 2026
3fb808c
fix(web): prompt recall pages older turns in once it passes the loade…
maria-rcks Oct 11, 2026
7196211
fix(server): the review preview sweep keeps previews still loading
maria-rcks Oct 11, 2026
468f35f
fix(web): an outside rewrite equal to the last rendered prompt still …
maria-rcks Oct 11, 2026
d071b34
fix(client-runtime): a new attempt on a held run stays last when an o…
maria-rcks Oct 11, 2026
ba659ca
fix(web): expanding the oldest loaded turn no longer fetches another …
maria-rcks Oct 11, 2026
4aade08
perf(web): an over-budget boot snapshot stops encoding once it passes…
maria-rcks Oct 11, 2026
68f4b48
chore: merge perf/wave2 7522dfd74d
maria-rcks Oct 11, 2026
1634ef4
chore: merge perf/wave2 0db57d88ed
maria-rcks Oct 11, 2026
74dd308
test(web): lineage panel tests mock the chat thread presentation it r…
maria-rcks Oct 11, 2026
68f46b2
test(web): theme sync tests give the fake document a body and theme-c…
maria-rcks Oct 11, 2026
edd11c8
chore: merge perf/wave2 2d3af6995c
maria-rcks Oct 11, 2026
1308561
test(server): the turn start memory fixture provides the checkpoint s…
maria-rcks Oct 11, 2026
dc74ba5
chore: drop hooks without callers and declare the desktop application…
maria-rcks Oct 11, 2026
b316e84
fix(server): viewport turn lists cover the last 10 user turns
maria-rcks Oct 11, 2026
dd6b734
fix(server): the schema cache no longer hides a missing thread read p…
maria-rcks Oct 11, 2026
dfa83ea
fix(server): review previews are read fresh once they finish
maria-rcks Oct 11, 2026
da8fdb4
fix(server): a baseline capture defect no longer blocks the turn
maria-rcks Oct 11, 2026
7244e76
fix(desktop): OTLP exports give up on a collector that never answers
maria-rcks Oct 11, 2026
dd9b1e5
fix(web): ArrowUp recall pages older prompts from an empty window, on…
maria-rcks Oct 11, 2026
2c66a69
fix(web): a superseded file save keeps its pending indicator
maria-rcks Oct 11, 2026
5f4a6c0
fix(web): the preview panel and composer overlay measure after a cold…
maria-rcks Oct 11, 2026
08e873f
fix(web): thread cache entries with deferred checkpoints use the enve…
maria-rcks Oct 11, 2026
fccc2b6
fix(web): new tabs read the cached shell from IndexedDB again
maria-rcks Oct 11, 2026
8179f58
fix(web): a shell cache format this build does not know is left in place
maria-rcks Oct 11, 2026
3979082
perf(web): history pages no longer refresh file metadata
maria-rcks Oct 11, 2026
e58f8c3
perf(client-runtime): superseded diff previews free after 30 s
maria-rcks Oct 11, 2026
0e0af77
fix(web): composer drafts save once typing pauses for 300 ms
maria-rcks Oct 11, 2026
aa4d6e2
fix(web): a concurrent render no longer rewinds composer typing
maria-rcks Oct 11, 2026
14b9759
fix(web): sidebar rows already in view mount with the list
maria-rcks Oct 11, 2026
697ecfe
fix(web): settings font previews hold their height until they load
maria-rcks Oct 11, 2026
da893c4
test(web): draft persistence writes once typing pauses
maria-rcks Oct 11, 2026
4f1f7a7
chore: merge t3/perf-wave2 final-review fixes
maria-rcks Oct 11, 2026
15a1b5d
fix(server): migration 063's loaders reference exports knip can see
maria-rcks Oct 11, 2026
5913a71
fix(web): prompt recall waiting for an older page ends on edit, send,…
maria-rcks Oct 11, 2026
2bd478e
fix(web): composer selection and focus work after a stale value is sk…
maria-rcks Oct 11, 2026
32d29ea
fix(server): viewport turn lists cover what a turn-aligned window covers
maria-rcks Oct 11, 2026
a1c6133
fix(web): a reopened diff panel shows its cached preview again
maria-rcks Oct 11, 2026
98f2568
fix(web): settings code font previews attach their diff before paint
maria-rcks Oct 11, 2026
f695b5f
fix(mobile): older bundles skip cached threads with deferred checkpoints
maria-rcks Oct 11, 2026
0de4c29
refactor(server): drop the review preview cacheKey path no client sends
maria-rcks Oct 11, 2026
dd49453
chore: merge t3/perf-wave2 round-3 fixes
maria-rcks Oct 11, 2026
d7dbcce
test(server): compile cache test follows the week-unused cleanup rule
maria-rcks Oct 11, 2026
bf4007b
chore: merge t3/perf-wave2 with #17609 37f8c26a4a
maria-rcks Oct 11, 2026
abb1f3b
fix(desktop): Linux captures no longer re-run the application entry
maria-rcks Oct 11, 2026
44d73d2
fix(desktop): a startup crash shows its cause
maria-rcks Oct 11, 2026
70d7c94
fix(server): a viewport keeps a turn whose rows sit above the window
maria-rcks Oct 11, 2026
3d2da8f
fix(server): agent-only threads list only their viewport's turns
maria-rcks Oct 11, 2026
9bbdfbb
fix(client-runtime): a deleted thread's cache entry stays deleted
maria-rcks Oct 11, 2026
645aa1d
fix(web): older builds no longer read a viewport thread cache as comp…
maria-rcks Oct 11, 2026
74af7be
perf(server): visits and provider updates repair a stale thread read row
maria-rcks Oct 11, 2026
a6822cb
fix(web): confirm dialogs animate in again
maria-rcks Oct 11, 2026
2a5fa31
fix(web): a reply row that mounts mid-stream paints its live text
maria-rcks Oct 11, 2026
ed4fef7
fix(web): branch toolbar labels compact before new label text paints
maria-rcks Oct 11, 2026
e75f35e
fix(web): sidebar rows that open into view animate instead of popping in
maria-rcks Oct 11, 2026
ee73554
fix(web): sidebar rows crossfade between card and slim
maria-rcks Oct 11, 2026
51dff76
chore: merge t3/perf-wave2 round-4 fixes
maria-rcks Oct 11, 2026
4182b1f
chore(perf): merge updated wave2 into wave3
maria-rcks Oct 11, 2026
3ea8e81
Merge branch 'perf/wave2' into perf/wave3
maria-rcks Oct 11, 2026
625f214
fix(server): normalize appended events like durable replay
maria-rcks Oct 12, 2026
0f89a24
chore(perf): merge updated wave2 into wave3
maria-rcks Oct 12, 2026
cccd9e6
chore(perf): merge wave2 fix into wave3
maria-rcks Oct 13, 2026
8529953
chore(perf): merge wave2 typing fix into wave3
maria-rcks Oct 13, 2026
9e7f6b8
chore(perf): merge wave2 typing fix into wave3
maria-rcks Oct 13, 2026
efabb9c
refactor(web): keep font preview implementation in its original file
maria-rcks Oct 14, 2026
ced377c
refactor(web): avoid sidebar tooltip call-site renames
maria-rcks Oct 14, 2026
1a1af2a
refactor(web): reuse deferred draft storage
maria-rcks Oct 14, 2026
a404863
refactor(web): reuse compact cache test data
maria-rcks Oct 14, 2026
81a8d25
refactor(web): keep parallel wasm compilation
maria-rcks Oct 14, 2026
6b6a1a3
refactor(server): preserve compact migration entries
maria-rcks Oct 14, 2026
9e14699
refactor(desktop): keep application wiring in the original main module
maria-rcks Oct 14, 2026
1eaaba0
refactor(deps): preserve unchanged legend patch headers
maria-rcks Oct 14, 2026
6653fba
refactor(server): drop lazy migrations and schema marker
maria-rcks Oct 14, 2026
9cb7de5
refactor(desktop): drop stack suppression and lazy updater
maria-rcks Oct 14, 2026
108a558
refactor(web): drop lazy appearance preview module
maria-rcks Oct 14, 2026
a171a47
refactor(web): simplify reusable markdown parse keys
maria-rcks Oct 14, 2026
db828e1
refactor(desktop): restore single-bundle entry to prevent chunk cycles
maria-rcks Oct 14, 2026
7cb1e80
chore(perf): merge slimmed wave2 into wave3
maria-rcks Oct 14, 2026
208d9d5
chore(perf): merge spawn host compatibility into wave3
maria-rcks Oct 14, 2026
ebc638c
fix(server): remove the superseded activity timestamp encoder
maria-rcks Oct 14, 2026
8620702
fix(web): preserve thread context attachments in selective drafts
maria-rcks Oct 14, 2026
96abc79
chore(perf): merge migration verification fix into wave3
maria-rcks Oct 14, 2026
2ecec9c
test(server): update read projection ledger repair coverage to migrat…
maria-rcks Oct 14, 2026
9207328
fix(deps): align the list patch checksum after merging main
maria-rcks Oct 14, 2026
24232b5
chore(perf): merge wave2 fix into wave3
maria-rcks Oct 14, 2026
09f77e5
refactor(server): drop checkpoint index cache
maria-rcks Oct 15, 2026
6b4c384
refactor(server): drop desktop light cli path
maria-rcks Oct 15, 2026
d4456a4
refactor(server): drop asynchronous compile cache cleanup
maria-rcks Oct 15, 2026
b4e20f4
refactor(server): drop parallel startup reads
maria-rcks Oct 15, 2026
fca43eb
refactor(server): simplify vcs status cache bound
maria-rcks Oct 15, 2026
09999bf
test(server): trim viewport snapshot tests
maria-rcks Oct 15, 2026
b367df9
test(server): trim baseline capture tests
maria-rcks Oct 15, 2026
fd4ccc2
test(server): trim shared stream encoding tests
maria-rcks Oct 15, 2026
af0d160
test(server): trim obsolete schema marker tests
maria-rcks Oct 15, 2026
9953788
test(server): trim inherited descriptor tests
maria-rcks Oct 15, 2026
e9dec10
test(server): trim baseline failure fixtures
maria-rcks Oct 15, 2026
dd33d58
test(server): simplify viewport history fixtures
maria-rcks Oct 15, 2026
02b30fd
test(server): consolidate migration repair coverage
maria-rcks Oct 15, 2026
c5ecba6
test(server): reuse vcs subscription fixture
maria-rcks Oct 15, 2026
dc41c3c
test(server): trim duplicate regression assertions
maria-rcks Oct 15, 2026
801b3ea
test(server): simplify regression subprocess setup
maria-rcks Oct 15, 2026
80ea5c6
refactor(server): simplify desktop startup dispatch
maria-rcks Oct 15, 2026
14eafc5
refactor(web): drop incremental shell cache writes
maria-rcks Oct 15, 2026
f3c6273
refactor(web): simplify deferred font previews
maria-rcks Oct 15, 2026
e30d8c5
refactor(web): drop layout element ref rewrite
maria-rcks Oct 15, 2026
31defdb
refactor(web): drop early boot snapshot budget encoding
maria-rcks Oct 15, 2026
2a3dbd4
refactor(web): drop deferred cache codec compilation
maria-rcks Oct 15, 2026
46b9b44
refactor(web): drop idle confirm dialog deferral
maria-rcks Oct 15, 2026
2b0fe18
refactor(web): drop unmeasured panel tab rewrites
maria-rcks Oct 15, 2026
565df6a
refactor(web): drop settings route intent preload
maria-rcks Oct 15, 2026
5ba520c
refactor(web): drop chrome palette lookup shortcut
maria-rcks Oct 15, 2026
1729bfd
refactor(web): simplify branch label observation
maria-rcks Oct 15, 2026
64a31b8
refactor(web): drop completed markdown parse cache
maria-rcks Oct 15, 2026
e2792fd
refactor(web): simplify composer initialization and traits inputs
maria-rcks Oct 15, 2026
f00ce51
refactor(web): drop sidebar layout box cache
maria-rcks Oct 15, 2026
414b986
refactor(web): simplify prompt recall attachment guard
maria-rcks Oct 15, 2026
d14caa1
refactor(web): drop thread cache compaction writes
maria-rcks Oct 15, 2026
7800f50
test(web): trim duplicate draft persistence tests
maria-rcks Oct 15, 2026
bbfb711
test(web): trim history window fixtures
maria-rcks Oct 15, 2026
7401ea4
test(web): trim duplicate sidebar swap fixtures
maria-rcks Oct 15, 2026
0b9816c
test(web): trim cache compatibility fixtures
maria-rcks Oct 15, 2026
40d3c10
test(web): preserve sidebar entry travel assertion
maria-rcks Oct 15, 2026
0a08e41
refactor(web): drop shared sidebar tooltip controller
maria-rcks Oct 15, 2026
b1e1523
refactor(web): keep sidebar row elements stable across viewport changes
maria-rcks Oct 15, 2026
72e9528
refactor(web): drop sidebar search row virtualization
maria-rcks Oct 15, 2026
6849ee7
refactor(web): simplify sidebar sortable row inputs
maria-rcks Oct 15, 2026
c7c38f1
test(web): trim streaming boundary fixture duplication
maria-rcks Oct 15, 2026
742eee7
refactor(web): preserve sidebar row intrinsic sizes
maria-rcks Oct 15, 2026
8f543cf
refactor(web): drop composer initial snapshot rewrite
maria-rcks Oct 15, 2026
8258440
refactor(web): drop branch animation width staging
maria-rcks Oct 15, 2026
ebc54d5
test(web): trim typing guard render assertions
maria-rcks Oct 15, 2026
3646200
refactor(web): drop idle cache write gate
maria-rcks Oct 15, 2026
329acca
refactor(web): drop hidden sidebar roster cache
maria-rcks Oct 15, 2026
7513a13
refactor(web): drop per-label sidebar clock subscriptions
maria-rcks Oct 15, 2026
90994d4
refactor(web): drop sidebar snapshot selector indirection
maria-rcks Oct 15, 2026
3956c81
test(web): trim duplicate guard and streaming cases
maria-rcks Oct 15, 2026
2e6c93c
refactor(web): simplify sidebar viewport setup
maria-rcks Oct 15, 2026
6272186
refactor(web): simplify measured thread cache compaction
maria-rcks Oct 15, 2026
b4fd571
test(web): preserve compact cache compatibility fixture
maria-rcks Oct 15, 2026
20ca857
refactor(web): preserve deferred prompt font preview
maria-rcks Oct 15, 2026
d606d00
refactor(web): preserve search row virtualization
maria-rcks Oct 15, 2026
ca5b188
refactor(web): retain unchanged sidebar row boxes
maria-rcks Oct 15, 2026
e6ce63a
refactor(web): retain simple sidebar row measurement
maria-rcks Oct 15, 2026
7d2ed8b
refactor(web): share sidebar tooltip roots
maria-rcks Oct 15, 2026
4a61af1
refactor(web): avoid containing empty sidebar slots
maria-rcks Oct 15, 2026
9e1e296
refactor(web): retain native panel tab scrolling
maria-rcks Oct 15, 2026
968e772
refactor(web): retain memoized search content
maria-rcks Oct 15, 2026
dd1889d
refactor(web): drop unmeasured list measurement override
maria-rcks Oct 15, 2026
1c8abe9
refactor(deps): drop theme deduplication override
maria-rcks Oct 15, 2026
91e0c22
refactor(client): simplify deferred checkpoint hydration
maria-rcks Oct 15, 2026
e028dc9
refactor(client): simplify unchanged shell reuse
maria-rcks Oct 15, 2026
b276273
refactor(client): drop speculative state reference caches
maria-rcks Oct 15, 2026
bc2af03
test(client): trim history support fixtures
maria-rcks Oct 15, 2026
87cfdc7
test(desktop): trim exporter and chunk regressions
maria-rcks Oct 15, 2026
7b69969
refactor(client): drop unmeasured projection slot shortcut
maria-rcks Oct 15, 2026
beb55ab
refactor(deps): simplify lockfile after override removal
maria-rcks Oct 15, 2026
39e5585
refactor(desktop): simplify bounded telemetry client
maria-rcks Oct 15, 2026
0ac6f9c
test(desktop): simplify chunk dependency assertion
maria-rcks Oct 15, 2026
454d9b5
refactor(desktop): infer bounded client from concrete service
maria-rcks Oct 15, 2026
7366ea8
test(desktop): reuse log export fixture for stalled collector
maria-rcks Oct 15, 2026
190bfce
test(client): await deleted cache cleanup directly
maria-rcks Oct 15, 2026
38ba6fb
test(client): reuse run fixtures for live history preservation
maria-rcks Oct 15, 2026
eb53800
refactor(perf): format the retained history and telemetry paths
maria-rcks Oct 15, 2026
8a478dc
refactor(client): drop unused vcs schema import
maria-rcks Oct 15, 2026
1180837
fix(client): retain deferred links when shell metadata changes
maria-rcks Oct 15, 2026
f101045
perf(client): retain shell and vcs reference reuse
maria-rcks Oct 15, 2026
c03ad32
perf(client): retain timeline item slots during updates
maria-rcks Oct 15, 2026
74ea77a
perf(web): retain deferred initial list measurement
maria-rcks Oct 15, 2026
f767145
refactor(web): drop low-gain initial measurement trial
maria-rcks Oct 15, 2026
38f651d
chore(perf): merge trimmed wave2 into wave3
maria-rcks Oct 15, 2026
43110e6
fix(web): retain prompt preview reveal after merge
maria-rcks Oct 15, 2026
36358b4
test(server): adapt vcs regression to full status payload
maria-rcks Oct 15, 2026
eb92a8e
chore(perf): merge wave2 startup fix into wave3
maria-rcks Oct 15, 2026
fc6577d
perf(server): restore parallel config discovery during boot
maria-rcks Oct 15, 2026
6c3101c
chore(perf): merge wave2 fix into wave3
maria-rcks Oct 15, 2026
2c6d87c
chore(perf): merge wave2 format fix into wave3
maria-rcks Oct 15, 2026
e1ff11f
style(web): format wave3 files
maria-rcks Oct 15, 2026
4edbe3d
chore(perf): merge current main into w3
maria-rcks Oct 15, 2026
e8e930e
chore(perf): merge current main into w3
maria-rcks Oct 16, 2026
882b9b7
fix(perf): align merged composer and cache tests with main
maria-rcks Oct 16, 2026
a5fe54e
chore(perf): merge shell readiness validation into w3
maria-rcks Oct 16, 2026
489e1d8
chore(perf): merge compact pr fix into w3
maria-rcks Oct 16, 2026
2b90759
chore(perf): merge desktop fix into w3
maria-rcks Oct 16, 2026
ca80faf
chore(perf): merge current main into w3
maria-rcks Oct 17, 2026
d3977f4
fix(web): retain local composer updates with compiler cleanup
maria-rcks Oct 17, 2026
b0f040b
fix(web): preserve compiler coverage after perf merge
maria-rcks Oct 17, 2026
7f2c3cf
chore(perf): merge review fixes into w3
maria-rcks Oct 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions apps/desktop/scripts/main-process-bundle.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as NodeChildProcess from "node:child_process";
import * as NodeFSP from "node:fs/promises";
import * as NodeOS from "node:os";
import * as NodePath from "node:path";
import * as NodeURL from "node:url";
import * as NodeVM from "node:vm";
import { build } from "vite-plus/pack";
import { assert, it } from "vite-plus/test";
Expand Down Expand Up @@ -110,6 +111,34 @@ void import("./linux.ts").then(({ result }) => process.emit("ready", result));`,
}
});

it("keeps the real desktop chunks from requiring the application entry", async () => {
// conf can evict the entry from the require cache. Lazy chunks must not require it.
const directory = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-desktop-chunks-"));
try {
assert.ok(Array.isArray(desktopConfig.pack));
const packConfig = desktopConfig.pack.find((config) =>
Object.values(config.entry ?? {}).includes("src/main.ts"),
);
assert.ok(packConfig);
await build({
...packConfig,
config: false,
cwd: NodeURL.fileURLToPath(new URL("..", import.meta.url)),
outDir: directory,
sourcemap: false,
onSuccess: undefined,
logLevel: "silent",
});
for (const filename of await NodeFSP.readdir(directory)) {
if (!filename.endsWith(".cjs") || filename === "main.cjs") continue;
const source = await NodeFSP.readFile(NodePath.join(directory, filename), "utf8");
assert.notMatch(source, /require\(["'`]\.\/(?:application|main)\.cjs["'`]\)/, filename);
}
} finally {
await NodeFSP.rm(directory, { recursive: true, force: true });
}
}, 120_000);

it("loads the emitted packaged boot entry and backend cache preload", async () => {
const directory = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "t3-desktop-boot-"));
try {
Expand Down
44 changes: 35 additions & 9 deletions apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Schema from "effect/Schema";
import * as TestClock from "effect/testing/TestClock";
import * as HttpClient from "effect/http/HttpClient";
import * as HttpClientResponse from "effect/http/HttpClientResponse";

Expand Down Expand Up @@ -76,18 +77,29 @@ interface ExportedRequest {
readonly body: string;
}

const layerCollector = (requests: Array<ExportedRequest>) =>
/**
* Answers every export with a 200 and keeps what was posted for assertions.
* `stallFirst` never answers the first export.
*/
const layerCollector = (
requests: Array<ExportedRequest>,
options?: { readonly stallFirst?: boolean },
) =>
Layer.succeed(
HttpClient.HttpClient,
HttpClient.make((request) =>
Effect.sync(() => {
Effect.suspend(() => {
requests.push({
url: request.url,
headers: request.headers,
body:
request.body._tag === "Uint8Array" ? new TextDecoder().decode(request.body.body) : "",
});
return HttpClientResponse.fromWeb(request, new Response(null, { status: 200 }));
return options?.stallFirst === true && requests.length === 1
? Effect.never
: Effect.succeed(
HttpClientResponse.fromWeb(request, new Response(null, { status: 200 })),
);
}),
),
);
Expand Down Expand Up @@ -384,7 +396,7 @@ describe("DesktopObservability", () => {
),
);

it.effect("exports main process log records to the configured logs endpoint", () => {
it.effect("exports log records after a stalled collector times out", () => {
const requests: Array<ExportedRequest> = [];
return Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
Expand All @@ -394,21 +406,29 @@ describe("DesktopObservability", () => {
const layerEnvironment = layerEnvironmentFor(baseDir, true, {
T3CODE_OTLP_LOGS_URL: "https://collector.example.com/v1/logs",
T3CODE_OTLP_HEADERS: "x-scope=desktop",
T3CODE_OTLP_EXPORT_INTERVAL_MS: "1000",
});
const tracePath = yield* Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
return environment.path.join(environment.logDir, "desktop.trace.ndjson");
}).pipe(Effect.provide(layerEnvironment));

yield* Effect.scoped(
Effect.logInfo("desktop log export").pipe(
Effect.withSpan("desktop-log-export-test"),
Effect.gen(function* () {
yield* Effect.logInfo("before the stall");
for (let second = 0; second < 15; second += 1) yield* TestClock.adjust("1 second");
yield* Effect.logInfo("desktop log export").pipe(
Effect.withSpan("desktop-log-export-test"),
);
for (let second = 0; second < 5; second += 1) yield* TestClock.adjust("1 second");
// Before shutdown, whose flush could hide a stuck exporter.
assert.isTrue(requests.some((request) => request.body.includes("desktop log export")));
}).pipe(
Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(layerEnvironment))),
),
);

assert.lengthOf(requests, 1);
const [request] = requests;
const request = requests.find((value) => value.body.includes("desktop log export"));
assert.strictEqual(request?.url, "https://collector.example.com/v1/logs");
assert.include(request?.body ?? "", "desktop log export");
assert.include(request?.body ?? "", "service.runtime");
Expand All @@ -424,7 +444,13 @@ describe("DesktopObservability", () => {
assert.lengthOf(record?.events ?? [], 0);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, layerCollector(requests), layerEmptyEnv)),
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
layerCollector(requests, { stallFirst: true }),
layerEmptyEnv,
),
),
);
});

Expand Down
35 changes: 34 additions & 1 deletion apps/desktop/src/app/DesktopObservability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import * as Scope from "effect/Scope";
import * as Semaphore from "effect/Semaphore";
import * as SynchronizedRef from "effect/SynchronizedRef";
import * as Tracer from "effect/Tracer";
import * as HttpClient from "effect/http/HttpClient";
import * as HttpClientError from "effect/http/HttpClientError";
import { OtlpExporter, OtlpLogger, OtlpTracer } from "effect/observability";

import * as DesktopEnvironment from "./DesktopEnvironment.ts";
Expand Down Expand Up @@ -591,6 +593,33 @@ const layerBackendOutputLogFactory = Layer.effect(
}),
);

// Bound both headers and body so a stalled collector cannot stop later exports.
const withOtlpTimeout = (client: HttpClient.HttpClient) =>
client.pipe(
HttpClient.transform((response, request) =>
response.pipe(
Effect.tap((received) => received.arrayBuffer),
Effect.timeoutOrElse({
duration: "10 seconds",
orElse: () =>
Effect.fail(
new HttpClientError.HttpClientError({
reason: new HttpClientError.TransportError({
request,
description: "OTLP export timed out",
}),
}),
),
}),
),
),
);

/**
* Logs and traces for the main process, assembled together because they share
* one read of the environment and Settings, and because a process gets exactly
* one logger set.
*/
const layerTelemetry = Layer.unwrap(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
Expand Down Expand Up @@ -678,7 +707,11 @@ const layerTelemetry = Layer.unwrap(
);

return layerOtelWarnings.pipe(
Layer.provideMerge(Layer.mergeAll(layerLogger, layerTracer)),
Layer.provideMerge(
Layer.mergeAll(layerLogger, layerTracer).pipe(
Layer.updateService(HttpClient.HttpClient, withOtlpTimeout),
),
),
Layer.provide(OtelEnvironment.layerResourceAttributes(endpoints.resourceAttributes)),
);
}),
Expand Down
3 changes: 2 additions & 1 deletion apps/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,10 @@ const layerDesktopClerk = DesktopClerk.layer.pipe(
Layer.provideMerge(ElectronApp.layer),
);

// node:http bypasses environment proxies and keeps undici out of the main bundle.
const layerDesktopApplicationRuntime = layerDesktopApplication.pipe(
Layer.provideMerge(NodeServices.layer),
Layer.provideMerge(NodeHttpClient.layerUndici),
Layer.provideMerge(NodeHttpClient.layerNodeHttp),
Layer.provideMerge(NetService.layer),
Layer.provideMerge(layerElectron),
);
Expand Down
5 changes: 4 additions & 1 deletion apps/desktop/src/preview/Manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
{ readonly semaphore: Semaphore.Semaphore; users: number }
>();
const tabLifecycleGenerations = new Map<string, number>();
let nextTabLifecycleGeneration = 0;

const attempt = <A>(errorContext: PreviewOperationContext, evaluate: () => A) =>
Effect.try({
Expand Down Expand Up @@ -1685,7 +1686,8 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
},
);
if (result.created) {
tabLifecycleGenerations.set(tabId, (tabLifecycleGenerations.get(tabId) ?? 0) + 1);
// Generations remain unique when a closed tab id is reused.
tabLifecycleGenerations.set(tabId, ++nextTabLifecycleGeneration);
}
yield* emit(tabId, result.state);
return result.state;
Expand Down Expand Up @@ -1724,6 +1726,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
] as const;
});
if (Option.isNone(tab)) return;
tabLifecycleGenerations.delete(tabId);
const closedTab = tab.value;
if (closedTab.webContentsId != null) {
yield* Effect.all(
Expand Down
5 changes: 3 additions & 2 deletions apps/desktop/src/snapShot/LinuxSnapShot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import { isKdeCaptureSession, type KdeCapturePaths } from "./KdeSnapShot.ts";
import { isGnomeCaptureSession, readPortalPng, resizeLinuxCapture } from "./linuxCaptureSession.ts";
export { readPortalPng, resizeLinuxCapture } from "./linuxCaptureSession.ts";
import { isHyprlandCaptureSession, type HyprlandCapturePaths } from "./HyprlandSnapShot.ts";
// The entry chunk also imports NiriSnapShot, so a lazy import of it would
// require application.cjs again, and conf evicts that from the require cache.
import { captureNiriWindow, checkNiriCaptureSupport, niriSocketPath } from "./NiriSnapShot.ts";

const PORTAL = "org.freedesktop.portal.Desktop";
const PORTAL_PATH = "/org/freedesktop/portal/desktop";
Expand Down Expand Up @@ -365,7 +368,6 @@ export class LinuxCaptureConnection {
export async function getLinuxCaptureSupport(appId: string) {
if (isHyprlandCaptureSession())
return { linuxBackend: "hyprland" as const, linuxFeedbackAvailable: false };
const { niriSocketPath, checkNiriCaptureSupport } = await import("./NiriSnapShot.ts");
const niri = niriSocketPath();
if (niri) {
await checkNiriCaptureSupport(niri);
Expand All @@ -392,7 +394,6 @@ export async function captureLinuxWindow(
const { captureHyprlandWindow } = await import("./HyprlandSnapShot.ts");
return captureHyprlandWindow(hyprlandPaths, options);
}
const { niriSocketPath, captureNiriWindow } = await import("./NiriSnapShot.ts");
const niri = niriSocketPath();
if (niri) return captureNiriWindow(niri);
const connection = new LinuxCaptureConnection();
Expand Down
37 changes: 37 additions & 0 deletions apps/mobile/src/connection/environment-cache-store.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as Schema from "effect/Schema";
import {
ORCHESTRATION_CACHE_SCHEMA_VERSION,
ORCHESTRATION_THREAD_CACHE_SCHEMA_VERSION,
StoredOrchestrationShellSnapshot,
StoredOrchestrationThreadSnapshot,
} from "@t3tools/client-runtime/platform";
import {
CommandId,
Expand All @@ -27,6 +30,10 @@ const PROJECT_ID = ProjectId.make("project-1");
const THREAD_ID = ThreadId.make("thread-1");
const PROVIDER_INSTANCE_ID = ProviderInstanceId.make("codex");
const NOW = DateTime.makeUnsafe("2026-07-29T12:00:00.000Z");
// How a bundle without the deferred-thread envelope decodes a cached thread.
const decodePlainStoredThread = Schema.decodeUnknownExit(
Schema.fromJsonString(StoredOrchestrationThreadSnapshot),
);
const SHELL_SNAPSHOT: OrchestrationV2ShellSnapshot = {
schemaVersion: 1,
snapshotSequence: 3,
Expand Down Expand Up @@ -246,6 +253,36 @@ describe("mobile SQLite environment cache store", () => {
expect(memory.schemaVersions.get(cacheId(ENVIRONMENT_ID, "thread", THREAD_ID))).toBe(
ORCHESTRATION_THREAD_CACHE_SCHEMA_VERSION,
);

// An older bundle reads deferred checkpoints' empty file lists as "no
// changes", so it must not be able to decode their entry.
yield* store.saveThread(ENVIRONMENT_ID, {
...THREAD_SNAPSHOT,
projection: {
...THREAD_SNAPSHOT.projection,
checkpoints: [
{
id: "checkpoint-deferred" as never,
threadId: THREAD_ID,
scopeId: "scope" as never,
runId: null,
nodeId: "node" as never,
parentCheckpointId: null,
ordinalWithinScope: 1,
appRunOrdinal: 1,
ref: "refs/t3/deferred" as never,
status: "ready",
files: [],
deferredFileCount: 2,
capturedAt: NOW,
},
],
},
});
const deferredPayload = memory.values.get(cacheId(ENVIRONMENT_ID, "thread", THREAD_ID))!;
expect(decodePlainStoredThread(deferredPayload)._tag).toBe("Failure");
const deferred = Option.getOrThrow(yield* store.loadThread(ENVIRONMENT_ID, THREAD_ID));
expect(deferred.projection.checkpoints[0]?.deferredFileCount).toBe(2);
}),
);

Expand Down
32 changes: 25 additions & 7 deletions apps/mobile/src/connection/environment-cache-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,24 @@ const StoredVcsRefs = Schema.Struct({
refs: VcsListRefsResult,
});

const decodeStoredThreadSnapshot = Schema.decodeUnknownEffect(
Schema.fromJsonString(StoredOrchestrationThreadSnapshot),
);
const encodeStoredThreadSnapshot = Schema.encodeEffect(
Schema.fromJsonString(StoredOrchestrationThreadSnapshot),
// Deferred checkpoints have empty file lists that an older bundle, after an
// OTA rollback, would show as turns with no changes. Their entries are
// wrapped, so an older bundle fails to decode them, drops them and loads live.
const StoredThreadCache = Schema.Union([
StoredOrchestrationThreadSnapshot,
Schema.Struct({
format: Schema.Literal("deferred-thread-1"),
stored: StoredOrchestrationThreadSnapshot,
}),
]);
const decodeStoredThreadCache = Schema.decodeUnknownEffect(
Schema.fromJsonString(StoredThreadCache),
);
const decodeStoredThreadSnapshot = (raw: string) =>
decodeStoredThreadCache(raw).pipe(
Effect.map((cached) => ("format" in cached ? cached.stored : cached)),
);
const encodeStoredThreadSnapshot = Schema.encodeEffect(Schema.fromJsonString(StoredThreadCache));
const decodeStoredServerConfig = Schema.decodeUnknownEffect(
Schema.fromJsonString(StoredServerConfig),
);
Expand Down Expand Up @@ -146,12 +158,18 @@ export const make = Effect.fn("MobileEnvironmentCacheStore.make")(function* () {
),
saveThread: Effect.fn("MobileEnvironmentCache.saveThread")(function* (environmentId, snapshot) {
const threadId = snapshot.projection.thread.id;
const payload = yield* encodeStoredThreadSnapshot({
const stored = {
schemaVersion: ORCHESTRATION_THREAD_CACHE_SCHEMA_VERSION,
environmentId,
threadId,
snapshot,
}).pipe(Effect.mapError((cause) => persistenceError("save-thread", cause)));
};
const deferred = snapshot.projection.checkpoints.some(
(checkpoint) => checkpoint.deferredFileCount !== undefined,
);
const payload = yield* encodeStoredThreadSnapshot(
deferred ? { format: "deferred-thread-1", stored } : stored,
).pipe(Effect.mapError((cause) => persistenceError("save-thread", cause)));
yield* database
.saveCache(
environmentId,
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/src/features/review/reviewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function checkpointTitle(checkpoint: ThreadCheckpointSummary): string {
}

function checkpointSubtitle(checkpoint: ThreadCheckpointSummary): string {
const fileCount = checkpoint.files.length;
const fileCount = checkpoint.deferredFileCount ?? checkpoint.files.length;
if (checkpoint.status !== "ready") {
return `Diff ${checkpoint.status}`;
}
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ if (
}
if (process.argv.length === 3 && command === "--version") {
process.stdout.write(`t3 v${packageJson.version}\n`);
} else if (command === "--bootstrap-fd" || command?.startsWith("--bootstrap-fd=")) {
const { runLightCli } = await import("./binLightCli.ts");
await runLightCli("desktop");
} else if (
command === "pair" ||
command === "auth" ||
Expand Down
Loading
Loading