Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
258 commits
Select commit Hold shift + click to select a range
069b224
fix(server): report short event loop stalls from startup
maria-rcks Oct 10, 2026
6fb73ea
perf(server): compact database reads and verified maintenance
maria-rcks Oct 10, 2026
651a422
perf(server): send repeated shell pull request stacks once
maria-rcks Oct 10, 2026
85097da
fix(server): discard failed online backup staging files
maria-rcks Oct 10, 2026
b8835f8
docs(server): clarify interrupted compaction backups
maria-rcks Oct 10, 2026
b3937c7
fix(server): retain pull request settlement timestamps
maria-rcks Oct 10, 2026
011bf89
perf(server): keep usage recovery reads compact
maria-rcks Oct 10, 2026
6457155
fix(server): thread read projection follows payloads written by any b…
maria-rcks Oct 10, 2026
cc140c7
perf(rpc): send vcs summaries and incremental server config
maria-rcks Oct 10, 2026
911bf75
perf(web): keep thread views mounted across switches and full pages
maria-rcks Oct 10, 2026
1d98432
perf(web): render only visible pull request rows
maria-rcks Oct 10, 2026
981ae98
perf(web): open long settings lists and server toggles at once
maria-rcks Oct 10, 2026
04a9785
perf(web): trim per-keystroke shortcut checks
maria-rcks Oct 10, 2026
eb49ee5
fix(web): pause media and keep editors made in a transition for kept …
maria-rcks Oct 10, 2026
f3dd7d0
perf(web): start loading a thread with the click that opens it
maria-rcks Oct 10, 2026
3843722
fix(web): keep a draft's chat view through its promotion
maria-rcks Oct 10, 2026
c8da558
perf(web): open new threads in the shown view and keep the left one i…
maria-rcks Oct 10, 2026
e3a46f4
perf(web): skip effect definition stacks while the app graph evaluates
maria-rcks Oct 10, 2026
2225b81
perf(web): take the sidebar motion baseline in the next frame
maria-rcks Oct 10, 2026
3086d0c
perf(web): load the nightly notice without the settings row
maria-rcks Oct 10, 2026
8792430
perf(web): resolve locale data on first use
maria-rcks Oct 10, 2026
a1ddc03
perf(client): keep equal server configs and projects stable across boot
maria-rcks Oct 10, 2026
a5b4d28
perf(web): stop chat view rerenders from fresh empty selections
maria-rcks Oct 10, 2026
7c5923c
perf(client): compare server configs with a plain structural walk and…
maria-rcks Oct 10, 2026
5c46ab8
perf(web): paint the first screen from a local boot snapshot
maria-rcks Oct 10, 2026
35cfcf6
perf(web): render before the session check when a snapshot exists
maria-rcks Oct 10, 2026
40b3f5b
perf(web): open the landing draft before the server answers
maria-rcks Oct 10, 2026
41d94b1
perf(web): load cached project icons before the first commit
maria-rcks Oct 10, 2026
f0d5310
fix(web): do not warn about reconnecting during the first connection
maria-rcks Oct 10, 2026
432c42d
perf(web): read and write the boot snapshot in proportion to its changes
maria-rcks Oct 10, 2026
674e6ff
fix(web): label the send button Connecting during a first connection …
maria-rcks Oct 10, 2026
b35b4d8
perf(web): connect while the first screen paints from the snapshot
maria-rcks Oct 10, 2026
a4f4f2d
perf(web): apply landing draft defaults as soon as the session answers
maria-rcks Oct 10, 2026
acd1944
perf(web): render the boot chat view with live data when the session …
maria-rcks Oct 10, 2026
736368a
perf(web): paint from the boot snapshot only on reloads and desktop w…
maria-rcks Oct 10, 2026
61d646c
perf(web): keep boot snapshot reads off the startup path
maria-rcks Oct 10, 2026
4e2ddd9
perf(web): hydrate boot-path settings and icons in their own task
maria-rcks Oct 10, 2026
1fffbd3
perf(desktop): open the main window without waiting for the login shell
maria-rcks Oct 10, 2026
70ab4dc
perf(desktop): serve renderer assets with one file read
maria-rcks Oct 10, 2026
b997cfb
docs(desktop): note that bootstrap may open the WSL splash instead of…
maria-rcks Oct 10, 2026
d4a01c2
fix(desktop): wait for the login shell before renderer invoke handlers
maria-rcks Oct 10, 2026
9f66e04
chore: clear lint warnings the integrated changes added
maria-rcks Oct 10, 2026
3898011
test(server): the V1 importer boundary allows the project layers module
maria-rcks Oct 10, 2026
5afc1fd
test: usage and bundled-dev tests follow the boot identity and stack …
maria-rcks Oct 10, 2026
ba9ffbe
fix(desktop): the Linux password store is chosen once, before Electro…
maria-rcks Oct 10, 2026
09ad1d3
perf(desktop): boot invoke handlers that never spawn skip the login s…
maria-rcks Oct 10, 2026
6195ecc
fix(desktop): quitting while the login shell starts no longer waits f…
maria-rcks Oct 10, 2026
c57ea6a
perf(desktop): the connection catalog and context menus skip the logi…
maria-rcks Oct 10, 2026
84abbfb
fix(server): automatic settlement loses to a pull request sync after …
maria-rcks Oct 10, 2026
cda6f2d
perf(server): older clients resume across a visit without a snapshot
maria-rcks Oct 10, 2026
8f12108
fix(server): the thread read projection exists when another build too…
maria-rcks Oct 10, 2026
19fea5d
fix(server): db compact does not compare the derived thread read rows
maria-rcks Oct 10, 2026
a6ee0f5
fix(server): waking from system sleep is not reported as an event loo…
maria-rcks Oct 10, 2026
3a7c7cd
fix(server): every update keeps a database backup for its rollback
maria-rcks Oct 10, 2026
5051799
fix(contracts): a provider delta an older client cannot read drops th…
maria-rcks Oct 10, 2026
152f327
fix(server): compact shells keep whole pull request stacks
maria-rcks Oct 10, 2026
f1c20ed
fix(server): source control discovery reruns after a credential change
maria-rcks Oct 10, 2026
e2b0a03
fix(cli): the compile cache skips AppImage and server helpers and kee…
maria-rcks Oct 10, 2026
39408ff
fix(server): the browser sandbox warning logs at startup again
maria-rcks Oct 10, 2026
e23357e
fix(web): a thread warming up out of sight no longer answers shortcuts
maria-rcks Oct 10, 2026
7ed9606
fix(web): undo in a thread never brings back another thread's prompt
maria-rcks Oct 10, 2026
29375b0
fix(web): idle and hover preloads no longer reload the page on a fail…
maria-rcks Oct 10, 2026
20761a8
fix(web): text typed while a search view loads becomes its query
maria-rcks Oct 10, 2026
c4b094a
chore(web): clear React Compiler hints in settings rows and scoped saves
maria-rcks Oct 10, 2026
5d279b3
fix(client-runtime): a session fetch that fails while connecting retries
maria-rcks Oct 10, 2026
2ebece4
fix(web): theme switches no longer animate the whole app
maria-rcks Oct 10, 2026
7d0bb82
fix(web): keybinding reloads from config deltas show their toast
maria-rcks Oct 10, 2026
b6c72d4
fix(web): an MCP app works again after its kept thread is shown again
maria-rcks Oct 10, 2026
dcc6a98
fix(web): terminals keep their surface across kept thread switches
maria-rcks Oct 10, 2026
5df17c3
fix(web): a thread warming up out of sight is not the placeholder for…
maria-rcks Oct 10, 2026
cdbd6ca
fix(web): returning from settings to a kept thread no longer flashes …
maria-rcks Oct 10, 2026
f24c6bb
fix(web): keys typed while a kept thread is revealed go to that thread
maria-rcks Oct 10, 2026
8d5c22c
fix(web): a browser preview in a warming thread stays hidden
maria-rcks Oct 10, 2026
039db38
fix(web): a snapshot boot whose server never answers settles instead …
maria-rcks Oct 10, 2026
164c9fb
fix(web): a landing draft gets its project defaults when git status a…
maria-rcks Oct 10, 2026
61bd056
fix(web): plan buttons and pending questions read the first connectio…
maria-rcks Oct 11, 2026
9708581
fix(web): the Nightly mobile beta notice shows on snapshot boots
maria-rcks Oct 11, 2026
4d323af
fix(web): a boot failure while the app's modules load says why it has…
maria-rcks Oct 11, 2026
5eb6f3c
fix(web): a kept view's diff panel shows its own thread
maria-rcks Oct 11, 2026
7b58a5f
fix(web): menus left open in a hidden thread no longer block shortcuts
maria-rcks Oct 11, 2026
12c1688
fix(web): a source control rescan in Settings reaches the publish dialog
maria-rcks Oct 11, 2026
0f072ac
fix(client-runtime): a commit dialog's file list comes from the serve…
maria-rcks Oct 11, 2026
17d6ba9
fix(web): a landing draft in a removed environment stops saying Conne…
maria-rcks Oct 11, 2026
f05b842
fix(web): drag-to-close on the pull requests page follows the rows on…
maria-rcks Oct 11, 2026
50ac5ef
fix(web): linked pull request rows do not show +0 -0 before their cou…
maria-rcks Oct 11, 2026
1827ede
perf(web): a terminal drawer open at boot paints with the composer
maria-rcks Oct 11, 2026
a457930
chore: merge main via t3/app-startup-performance-audit
maria-rcks Oct 11, 2026
7522dfd
chore: merge t3/app-startup-performance-audit d77941686b
maria-rcks Oct 11, 2026
38b3460
fix(server): opencode's lazy text generation includes review guides
maria-rcks Oct 11, 2026
0db57d8
test(server): Claude runner tests read the runner service from its mo…
maria-rcks Oct 11, 2026
5f3d834
chore: drop exports the lazy provider drivers and kept thread views l…
maria-rcks Oct 11, 2026
2d3af69
test(scripts): the Cursor packaging probe loads the SDK through loadC…
maria-rcks Oct 11, 2026
15bff9d
fix(server): a hosted child's unread output sockets close when it exits
maria-rcks Oct 11, 2026
f92a9d3
fix(server): a spawn while the spawn host shuts down no longer crashe…
maria-rcks Oct 11, 2026
c77a714
fix(server): a spawn host crash leaves unreferenced children running
maria-rcks Oct 11, 2026
13c9e67
fix(desktop): the server sidecar self-check loads the whole server bu…
maria-rcks Oct 11, 2026
8412c14
fix(server): a failed lazy load is retried on next use
maria-rcks Oct 11, 2026
4c7d849
fix(server): desktop preview tabs reconnect when the desktop attaches…
maria-rcks Oct 11, 2026
3d0a428
fix(web): send works again after a kept thread view warms up
maria-rcks Oct 11, 2026
ca15135
fix(shared): config deltas clear provider fields set to undefined
maria-rcks Oct 11, 2026
53483b0
fix(client-runtime): a delta that drops a provider resyncs the config
maria-rcks Oct 11, 2026
a911439
fix(web): fixing an invalid keybindings file shows Keybindings update…
maria-rcks Oct 11, 2026
6bbaa56
fix(web): a chunk that fails while a preload runs still reloads its r…
maria-rcks Oct 11, 2026
d7978d6
fix(web): a popup left open in a hidden thread no longer blocks panel…
maria-rcks Oct 11, 2026
8853726
fix(web): Enter and Backspace on the way to a kept thread no longer a…
maria-rcks Oct 11, 2026
fa32a11
fix(web): the boot snapshot leaves room for draft images and skips un…
maria-rcks Oct 11, 2026
99d694c
fix(web): the thread pull request panel lists the live links after a …
maria-rcks Oct 11, 2026
33c694b
fix(mobile): the commit sheet says no files instead of loading forever
maria-rcks Oct 11, 2026
fa48824
fix(server): migration 63 rebuilds thread read rows that early builds…
maria-rcks Oct 11, 2026
c140af3
fix(server): a failed online backup no longer leaves the server stuck…
maria-rcks Oct 11, 2026
79b8374
fix(server): t3 db compact cleans up after itself and names a kept ba…
maria-rcks Oct 11, 2026
0c6b8de
fix(web): popups from a hidden or warming thread view no longer cover…
maria-rcks Oct 11, 2026
20ef997
fix(web): hovering a link to the thread list no longer resets the ope…
maria-rcks Oct 11, 2026
10af1df
fix(web): a landing draft moved to another machine keeps it and can send
maria-rcks Oct 11, 2026
bd0c547
fix(web): edit and recall keys on the way to a kept thread no longer …
maria-rcks Oct 11, 2026
b1f07c0
fix(web): desktop menu actions no longer reach a thread warming up ou…
maria-rcks Oct 11, 2026
d9f10c9
fix(web): fixing a keybindings file that was invalid at a reload show…
maria-rcks Oct 11, 2026
6f3c634
fix(desktop): update requests wait for the updater's configuration
maria-rcks Oct 11, 2026
ee5d04a
fix(desktop): saved connections on Linux wait for the login shell's s…
maria-rcks Oct 11, 2026
d26e2da
fix(desktop): a settings change right after launch is saved before a …
maria-rcks Oct 11, 2026
21c5441
fix(server): the event loop monitor samples finely only during startup
maria-rcks Oct 11, 2026
4514cbc
fix(server): installs of different versions keep each other's compile…
maria-rcks Oct 11, 2026
efea745
fix(server): OpenCode 2 and thread search retry a failed lazy load
maria-rcks Oct 11, 2026
407435f
fix(server): a failed browser load no longer stops preview tab mirror…
maria-rcks Oct 11, 2026
16d469e
fix(web): desktop-local backends no longer vanish from the first screen
maria-rcks Oct 11, 2026
d952854
fix(web): a pull request row keeps its pending action when it scrolls…
maria-rcks Oct 11, 2026
677ef91
fix(web): a removed and re-paired environment no longer shows its boo…
maria-rcks Oct 11, 2026
dde4703
test(server): compile cache test follows the week-unused cleanup rule
maria-rcks Oct 11, 2026
d722657
chore: merge t3/app-startup-performance-audit 37f8c26a4a
maria-rcks Oct 11, 2026
b217caa
fix(web): sidebar menus and tooltips no longer stay over settings
maria-rcks Oct 11, 2026
f028ae1
fix(desktop): an early settings save no longer leaves the SnapShot sh…
maria-rcks Oct 11, 2026
c8c8879
fix(desktop): Check for Updates in the app menu waits for the updater
maria-rcks Oct 11, 2026
4ce07ba
fix(web): a WSL backend that answers after the primary keeps its boot…
maria-rcks Oct 11, 2026
f558b47
fix(web): a reused landing draft on another machine still gets its de…
maria-rcks Oct 11, 2026
09fc610
fix(web): a landing draft moved by load balancing still gets its defa…
maria-rcks Oct 11, 2026
9685abb
fix(web): the keybindings toast compares against the server, not the …
maria-rcks Oct 11, 2026
7736f30
fix(web): a thread view warming out of sight no longer locks the page
maria-rcks Oct 11, 2026
873bfdd
chore(perf): merge updated startup base into wave2
maria-rcks Oct 11, 2026
b7a8469
test(server): use extracted event sink layer in queue fixture
maria-rcks Oct 11, 2026
0a891c2
chore(perf): merge updated startup base into wave2
maria-rcks Oct 12, 2026
aa2d488
fix(server): keep hosted child stdin resets from crashing the server
maria-rcks Oct 13, 2026
4ce569d
fix(web): keep keys typed right after picking a thread in the sidebar
maria-rcks Oct 13, 2026
2142c7d
fix(web): keep sidebar typing until composer autofocus
maria-rcks Oct 13, 2026
45161b0
refactor(server): keep lazy implementations in their original files
maria-rcks Oct 14, 2026
729a297
refactor(web): trim perf component comments and duplicate types
maria-rcks Oct 14, 2026
7323c50
refactor(web): trim perf wave2 commentary
maria-rcks Oct 14, 2026
0b1f36f
refactor(server): trim adapter test churn and projection comments
maria-rcks Oct 14, 2026
b9b6dc2
refactor(server): trim duplicated startup commentary
maria-rcks Oct 14, 2026
e2dd45f
refactor(perf): shorten startup and transport comments
maria-rcks Oct 14, 2026
53efb7b
refactor(client-runtime): use schema equality in usage tests
maria-rcks Oct 14, 2026
2ad289a
refactor(server): drop offline database compaction
maria-rcks Oct 14, 2026
ab36194
refactor(server): drop compact usage recovery queries
maria-rcks Oct 14, 2026
7fcb6aa
refactor(source-control): drop discovery ttl caches
maria-rcks Oct 14, 2026
788f15b
refactor(vcs): simplify summary subscriptions
maria-rcks Oct 14, 2026
5c03a0d
refactor(web): drop early landing draft reconciliation
maria-rcks Oct 14, 2026
8359f32
refactor(web): drop optimistic server settings overlay
maria-rcks Oct 14, 2026
eae7f90
refactor(shared): drop last-platform modifier cache
maria-rcks Oct 14, 2026
5c11ada
refactor(web): drop saved terminal speculative preload
maria-rcks Oct 14, 2026
f882371
test(vcs): preserve fresh summary remount coverage
maria-rcks Oct 14, 2026
287ca99
refactor(vcs): remove unused crypto diagnostic override
maria-rcks Oct 14, 2026
fd815e5
chore(perf): merge slimmed startup layer into wave2
maria-rcks Oct 14, 2026
11f3edb
fix(server): move the read payload migration after the sweep indexes
maria-rcks Oct 14, 2026
3daab1f
fix(server): keep the spawn host hook with Effect 4.0.4
maria-rcks Oct 14, 2026
1222df6
test(server): check sweep indexes after migration 63
maria-rcks Oct 14, 2026
fe107b4
test(server): tolerate approximate sqlite planner statistics
maria-rcks Oct 14, 2026
5383c9c
refactor(server): drop lazy cloud link split
maria-rcks Oct 15, 2026
1e81276
refactor(server): drop lazy mcp app request split
maria-rcks Oct 15, 2026
8b0c5e2
refactor(server): drop lazy usage service split
maria-rcks Oct 15, 2026
d7fc6fa
refactor(server): drop lazy server browser split
maria-rcks Oct 15, 2026
a351c70
refactor(cli): drop filesystem compile cache
maria-rcks Oct 15, 2026
d195a09
refactor(server): drop conditional config delta protocol
maria-rcks Oct 15, 2026
0108613
test(server): trim dropped recovery query coverage
maria-rcks Oct 15, 2026
f25a13f
refactor(server): drop unused database compaction helper
maria-rcks Oct 15, 2026
3900dc8
refactor(server): drop file-free vcs summaries
maria-rcks Oct 15, 2026
b3bccaa
refactor(server): drop legacy visit replay optimization
maria-rcks Oct 15, 2026
da6c382
test(server): trim duplicate projection and spawn coverage
maria-rcks Oct 15, 2026
cb86b86
refactor(server): drop shell stack wire references
maria-rcks Oct 15, 2026
f020094
refactor(server): simplify lazy sdk service acquisition
maria-rcks Oct 15, 2026
6d35db9
test(server): trim redundant cli and usage setup coverage
maria-rcks Oct 15, 2026
3eb7ea0
refactor(server): simplify inferred sdk layer types
maria-rcks Oct 15, 2026
6f4eabe
test(server): remove stale shell reference import
maria-rcks Oct 15, 2026
f690af0
refactor(cli): retain measured warm startup compile cache
maria-rcks Oct 15, 2026
d1f27a0
refactor(server): drop separate offline project layers
maria-rcks Oct 15, 2026
bae61ed
refactor(server): finish consolidating project layers
maria-rcks Oct 15, 2026
00e11ff
test(server): trim duplicate version and process timeout coverage
maria-rcks Oct 15, 2026
71abf7f
refactor(server): drop redundant discovery refresh alias
maria-rcks Oct 15, 2026
2d0fcce
refactor(web): simplify kept thread views
maria-rcks Oct 15, 2026
de89da9
refactor(web): drop speculative sidebar layout baseline
maria-rcks Oct 15, 2026
4ebc450
refactor(web): drop app import stack suppression
maria-rcks Oct 15, 2026
4ce9714
refactor(web): drop lazy calendar locale cache
maria-rcks Oct 15, 2026
ce44d48
refactor(web): drop unmeasured empty atom caches
maria-rcks Oct 15, 2026
b27b2d2
refactor(web): drop unmeasured shortcut selector change
maria-rcks Oct 15, 2026
b7ab241
refactor(web): drop nightly notice module split
maria-rcks Oct 15, 2026
adf939b
refactor(web): drop synchronous boot snapshot
maria-rcks Oct 15, 2026
01fb4f7
test(web): trim duplicate performance regression setup
maria-rcks Oct 15, 2026
bf14c06
refactor(web): simplify retained composer editor
maria-rcks Oct 15, 2026
3296a88
refactor(web): drop unmeasured citation selector cache
maria-rcks Oct 15, 2026
8639a6e
refactor(web): simplify kept view render props
maria-rcks Oct 15, 2026
80ad6b3
refactor(web): simplify virtual pull request row updates
maria-rcks Oct 15, 2026
f271186
test(web): combine retained view regression fixtures
maria-rcks Oct 15, 2026
2df7c6f
refactor(web): simplify editor content identity
maria-rcks Oct 15, 2026
eead332
refactor(web): share virtual row spacing
maria-rcks Oct 15, 2026
7fe8d34
refactor(web): drop sidebar retention on settings
maria-rcks Oct 15, 2026
e9c2055
test(web): trim duplicate palette state assertion
maria-rcks Oct 15, 2026
0e2b199
refactor(web): drop speculative thread detail mount
maria-rcks Oct 15, 2026
2ecfbea
refactor(web): trim repeated typing buffer explanation
maria-rcks Oct 15, 2026
f976d04
test(web): use supported promise API in chunk regression
maria-rcks Oct 15, 2026
170303c
perf(web): restore app import stack suppression
maria-rcks Oct 15, 2026
f48704c
refactor(github): drop lazy service splits
maria-rcks Oct 15, 2026
b3305bd
refactor(opencode): drop client interface split
maria-rcks Oct 15, 2026
bd2b8b2
refactor(client): drop config reconnect acknowledgements
maria-rcks Oct 15, 2026
8138984
refactor(client): drop partial config application
maria-rcks Oct 15, 2026
e4ca93d
test(desktop): trim update menu regression fixture
maria-rcks Oct 15, 2026
6d6c369
test(provider): trim lazy adapter fixtures
maria-rcks Oct 15, 2026
cb3ed98
test(client): trim shared stack fixtures
maria-rcks Oct 15, 2026
3786965
refactor(opencode): simplify lazy sdk loading
maria-rcks Oct 15, 2026
903f216
refactor(shared): drop lazy usage formatters
maria-rcks Oct 15, 2026
7d91f72
refactor(desktop): drop renderer asset read shortcut
maria-rcks Oct 15, 2026
6cd2af1
test(client): keep legacy sign-out regression
maria-rcks Oct 15, 2026
99b25cb
refactor(opencode): simplify deferred event decoding
maria-rcks Oct 15, 2026
8acadba
chore(perf): merge trimmed startup layer into wave2
maria-rcks Oct 15, 2026
28dccfd
test(web): repair merged chunk failure fixture
maria-rcks Oct 15, 2026
52e96a1
perf(runtime): retain measured checkpoint compaction
maria-rcks Oct 15, 2026
84475e7
perf(web): retain measured thread recycling and details boundary
maria-rcks Oct 15, 2026
3db42f3
perf(web): overlap desktop authentication and shell reads
maria-rcks Oct 15, 2026
0f2113c
refactor(web): remove ineffective desktop shell prefetch
maria-rcks Oct 15, 2026
e7d69e8
perf(web): reuse native registration during startup
maria-rcks Oct 15, 2026
e45e7cd
perf(web): overlap cached browser startup reads
maria-rcks Oct 15, 2026
7deae9c
chore(perf): merge wave1 fix into wave2
maria-rcks Oct 15, 2026
62a1f28
style(server): format the migration test
maria-rcks Oct 15, 2026
90b428a
chore(perf): merge current main into w2
maria-rcks Oct 15, 2026
45383f7
chore(perf): merge current main into w2
maria-rcks Oct 16, 2026
b7f3068
chore(perf): merge startup validation fix into w2
maria-rcks Oct 16, 2026
cecf1e5
fix(desktop): align shell readiness test services with main
maria-rcks Oct 16, 2026
9c57ac1
chore(perf): merge compact pr fix into w2
maria-rcks Oct 16, 2026
53b04eb
fix(desktop): keep login shell off the window launch path
maria-rcks Oct 16, 2026
c6ac555
chore(perf): merge current main into w2
maria-rcks Oct 17, 2026
1607f44
fix(web): keep sidebar typing until the composer accepts it
maria-rcks Oct 17, 2026
4f439e9
fix(web): retain the cached primary during failed discovery
maria-rcks Oct 17, 2026
1a2a1fb
chore(perf): merge current main into wave2
maria-rcks Oct 19, 2026
1439bda
fix(server): move wave2 read projection to migration 066
maria-rcks Oct 19, 2026
d72ba5f
chore(perf): merge isolated migration validation into wave2
maria-rcks Oct 19, 2026
7a06ad2
fix(perf): preserve main component extraction and lazy provider errors
maria-rcks Oct 19, 2026
7005592
chore(perf): merge lazy markdown browser validation into wave2
maria-rcks Oct 19, 2026
dc8b635
fix(web): preserve kept editor lifecycle under main compiler rules
maria-rcks Oct 19, 2026
c973200
chore(perf): merge latest main telemetry into wave2
maria-rcks Oct 19, 2026
96c8ef6
fix(server): release backup reader when staging setup fails
maria-rcks Oct 19, 2026
9ede4da
fix(desktop): select linux secret storage after shell hydration
maria-rcks Oct 19, 2026
462c56d
fix(web): restore retained terminal visibility on session changes
maria-rcks Oct 19, 2026
7b308e0
refactor(server): move deferred provider catalogs into the config domain
maria-rcks Oct 19, 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
90 changes: 40 additions & 50 deletions apps/desktop/src/app/DesktopApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import * as DesktopLegacyLocalStorage from "./DesktopLegacyLocalStorage.ts";
import * as DesktopLifecycle from "./DesktopLifecycle.ts";
import * as DesktopLinuxUrlHandler from "./DesktopLinuxUrlHandler.ts";
import * as DesktopObservability from "./DesktopObservability.ts";
import * as DesktopPreReadyPlatform from "./DesktopPreReadyPlatform.ts";
import * as DesktopShutdown from "./DesktopShutdown.ts";
import * as DesktopServerExposure from "../backend/DesktopServerExposure.ts";
import * as DesktopAppSettings from "../settings/DesktopAppSettings.ts";
Expand All @@ -35,7 +34,6 @@ import * as DesktopUpdates from "../updates/DesktopUpdates.ts";
import * as DesktopSnapShot from "../snapShot/DesktopSnapShot.ts";
import * as DesktopWslBackend from "../wsl/DesktopWslBackend.ts";
import * as DesktopRendererHistory from "../telemetry/DesktopRendererHistory.ts";
import * as HostProcess from "@t3tools/shared/HostProcess";

const DEFAULT_DESKTOP_BACKEND_PORT = 3773;
const MAX_TCP_PORT = 65_535;
Expand Down Expand Up @@ -166,6 +164,13 @@ const bootstrap = Effect.gen(function* () {
const desktopWindow = yield* DesktopWindow.DesktopWindow;
const snapShot = yield* DesktopSnapShot.DesktopSnapShot;
const appActivation = yield* DesktopAppActivation.DesktopAppActivation;
const shellEnvironment = yield* DesktopShellEnvironment.DesktopShellEnvironment;
const shutdown = yield* DesktopShutdown.DesktopShutdown;
// A quit during shell startup must prevent subsequent bootstrap work.
const awaitShellEnvironment = Effect.raceFirst(
shellEnvironment.installIntoProcess.pipe(Effect.as(true)),
shutdown.awaitRequest.pipe(Effect.as(false)),
);
yield* logBootstrapInfo("bootstrap start");

const settings = yield* desktopSettings.get;
Expand All @@ -184,13 +189,14 @@ const bootstrap = Effect.gen(function* () {
yield* (yield* DesktopAppIdentity.DesktopAppIdentity).resolveUserDataPath,
);

yield* snapShot.initialize;

if (!settings.localEnvironmentEnabled) {
yield* logBootstrapInfo("bootstrap skipping local environment (disabled in settings)");
if (!(yield* Ref.get(state.quitting))) {
yield* desktopWindow.createMainIfBackendReady;
}
// Snap Shot reads the desktop session variables the login shell provides.
if (!(yield* awaitShellEnvironment)) return;
yield* snapShot.initialize;
return;
}

Expand Down Expand Up @@ -239,17 +245,22 @@ const bootstrap = Effect.gen(function* () {
}

if (!(yield* Ref.get(state.quitting))) {
if (settings.wslOnly === true && settings.wslBackendEnabled === true) {
const wslOnly = settings.wslOnly === true && settings.wslBackendEnabled === true;
// The main window waits for the primary backend. In wsl-only mode that is
// the WSL backend, which can be slow to cold-boot — show a "Connecting to
// WSL" splash immediately so the app feels responsive instead of presenting
// no window until WSL is ready. (Dual mode opens fast off the Windows
// primary, so no splash there.)
if (wslOnly) {
yield* desktopWindow.showConnectingSplash;
// Resolving the WSL primary's config runs wsl.exe.
if (!(yield* awaitShellEnvironment)) return;
}
yield* primaryBackend.start;
yield* logBootstrapInfo("bootstrap backend start requested");
// The renderer loads bundled assets and can connect while the backend
// boots. Starting first makes its endpoint and bootstrap credential
// available before the preload reads them. WSL-only retains its splash
// until the primary has a usable endpoint. A failed open is not fatal:
// backend readiness tries again.
if (!(settings.wslOnly === true && settings.wslBackendEnabled === true)) {
// Publish the endpoint and token before preload reads them. Backend readiness
// retries a failed window open; WSL keeps its splash until then.
if (!wslOnly) {
yield* desktopWindow.ensureMain.pipe(
Effect.catch((error) =>
logBootstrapWarning("failed to open main window while the backend starts", {
Expand All @@ -258,6 +269,9 @@ const bootstrap = Effect.gen(function* () {
),
);
}
// Snap Shot reads the desktop session variables the login shell provides.
if (!(yield* awaitShellEnvironment)) return;
yield* snapShot.initialize;
yield* appActivation.start.pipe(
Effect.tap(() => logBootstrapInfo("desktop app control socket ready")),
Effect.catch((error) => logStartupError("desktop app control socket unavailable", { error })),
Expand All @@ -275,50 +289,19 @@ const startup = Effect.gen(function* () {
const clerk = yield* DesktopClerk.DesktopClerk;
const shellEnvironment = yield* DesktopShellEnvironment.DesktopShellEnvironment;
const desktopSettings = yield* DesktopAppSettings.DesktopAppSettings;
const preReadyElectronOptions = yield* DesktopPreReadyPlatform.DesktopPreReadyElectronOptions;
const safeStorage = yield* ElectronSafeStorage.ElectronSafeStorage;
const updates = yield* DesktopUpdates.DesktopUpdates;
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const previewPasskeys = yield* PreviewPasskeys.PreviewPasskeys;
const state = yield* DesktopState.DesktopState;

yield* shellEnvironment.installIntoProcess;
const hasCommandLinePasswordStore =
preReadyElectronOptions.linuxPasswordStoreCommandLine !== null;
const linuxElectronOptions =
environment.platform === "linux" && !hasCommandLinePasswordStore
? DesktopPreReadyPlatform.resolveEarlyLinuxElectronOptionsFromProcess(
yield* HostProcess.HomeDirectory,
)
: preReadyElectronOptions.linux;
if (linuxElectronOptions !== null && !hasCommandLinePasswordStore) {
if (
linuxElectronOptions.passwordStore !== null ||
preReadyElectronOptions.linux?.passwordStore !== null
) {
yield* electronApp.removeCommandLineSwitch("password-store");
}
if (linuxElectronOptions.passwordStore !== null) {
yield* electronApp.appendCommandLineSwitch(
"password-store",
linuxElectronOptions.passwordStore,
);
}
}
// Open the window while the shell loads; spawning work awaits the same run.
yield* Effect.forkScoped(shellEnvironment.installIntoProcess);
const userDataPath = yield* appIdentity.resolveUserDataPath;
yield* electronApp.setPath("userData", userDataPath);
yield* logStartupInfo("runtime logging configured", { logDir: environment.logDir });
yield* desktopSettings.load;

if (linuxElectronOptions !== null) {
yield* logStartupInfo("linux password store configured", {
passwordStore: hasCommandLinePasswordStore
? "command-line"
: (linuxElectronOptions.passwordStore ?? "electron-default"),
xdgCurrentDesktop: process.env.XDG_CURRENT_DESKTOP ?? null,
xdgSessionDesktop: process.env.XDG_SESSION_DESKTOP ?? null,
});
}

yield* appIdentity.configure;
yield* lifecycle.register;
yield* clerk.configure;
Expand All @@ -329,18 +312,25 @@ const startup = Effect.gen(function* () {
);
yield* logStartupInfo("app ready");
if (environment.platform === "linux") {
const selectedBackend = yield* safeStorage.selectedStorageBackend;
yield* logStartupInfo("safe storage ready", {
backend: Option.getOrElse(selectedBackend, () => "unknown"),
});
yield* Effect.forkScoped(
shellEnvironment.secretStorageReady.pipe(
Effect.andThen(safeStorage.selectedStorageBackend),
Effect.flatMap((selectedBackend) =>
logStartupInfo("safe storage ready", {
backend: Option.getOrElse(selectedBackend, () => "unknown"),
}),
),
),
);
}
yield* appIdentity.configure;
yield* previewPasskeys.configure;
yield* applicationMenu.configure;
yield* bootstrap.pipe(Effect.catchCause((cause) => fatalStartupCause("bootstrap", cause)));
if (yield* Ref.get(state.quitting)) return;
yield* updates.configure;
yield* DesktopRemoteUpdates.listen;
yield* linuxUrlHandler.register;
yield* bootstrap.pipe(Effect.catchCause((cause) => fatalStartupCause("bootstrap", cause)));
}).pipe(Effect.withSpan("desktop.startup"));

const scopedProgram = Effect.scoped(
Expand Down
7 changes: 5 additions & 2 deletions apps/desktop/src/backend/DesktopBackendConfiguration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const isDesktopBackendObservabilitySettingsReadError = Schema.is(
const layerShellEnvironment = (prepared = true) =>
Layer.succeed(DesktopShellEnvironment.DesktopShellEnvironment, {
installIntoProcess: Effect.succeed(prepared),
secretStorageReady: Effect.void,
});

const layerBackendConfiguration = (prepared = true) =>
Expand Down Expand Up @@ -124,6 +125,7 @@ const withHarness = <A, E, R>(
| DesktopBackendConfiguration.DesktopBackendConfiguration
>,
prepared = true,
platform: NodeJS.Platform = "darwin",
) =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
Expand All @@ -138,7 +140,7 @@ const withHarness = <A, E, R>(
Layer.provideMerge(DesktopAppSettings.layerTest()),
Layer.provideMerge(DesktopWslEnvironment.layerTest()),
Layer.provideMerge(DesktopWslServerTree.layerTest()),
Layer.provideMerge(layerEnvironment(baseDir)),
Layer.provideMerge(layerEnvironment(baseDir, { platform })),
),
),
);
Expand Down Expand Up @@ -347,14 +349,15 @@ describe("DesktopBackendConfiguration", () => {
),
);

it.effect("keeps server hydration enabled when desktop preparation failed", () =>
it.effect("keeps server hydration enabled when Windows preparation failed", () =>
withHarness(
Effect.gen(function* () {
const configuration = yield* DesktopBackendConfiguration.DesktopBackendConfiguration;
const primary = yield* configuration.resolvePrimary;
assert.equal(primary.bootstrap.shellEnvironmentPrepared, false);
}),
false,
"win32",
),
);

Expand Down
7 changes: 6 additions & 1 deletion apps/desktop/src/backend/DesktopBackendConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,12 @@ export const make = Effect.gen(function* () {
Effect.provideService(FileSystem.FileSystem, fileSystem),
Effect.provideService(DesktopEnvironment.DesktopEnvironment, environment),
);
const shellEnvironmentPrepared = yield* shellEnvironment.installIntoProcess;
// POSIX installation always returns true and runs at the spawn gate. Keep
// Windows probes here so a failure still enables server-side hydration.
const shellEnvironmentPrepared =
environment.platform === "darwin" ||
environment.platform === "linux" ||
(yield* shellEnvironment.installIntoProcess);
return yield* resolvePrimaryStartConfig({
...shared,
resourceMonitorPath,
Expand Down
38 changes: 38 additions & 0 deletions apps/desktop/src/backend/DesktopBackendManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ interface MakeInstanceInput {
DesktopTelemetryPublisher.DesktopTelemetryPublisher["Service"]
>;
readonly pruneRuntimes?: (distro: string | null, runtimeId: string) => Effect.Effect<void>;
readonly beforeSpawn?: Effect.Effect<void>;
}

function makeTestInstance(input: MakeInstanceInput) {
Expand Down Expand Up @@ -187,6 +188,7 @@ function makeTestInstance(input: MakeInstanceInput) {
...(input.onShutdown ? { onShutdown: () => input.onShutdown! } : {}),
...(input.onStateDirOwned ? { onStateDirOwned: () => input.onStateDirOwned! } : {}),
...(input.onPreflightFailed ? { onPreflightFailed: input.onPreflightFailed } : {}),
...(input.beforeSpawn ? { beforeSpawn: input.beforeSpawn } : {}),
});

return instance.pipe(Effect.provide(layerServices));
Expand Down Expand Up @@ -935,6 +937,42 @@ describe("DesktopBackendManager", () => {
),
);

it.effect("publishes its config before the spawn gate and never spawns once stopped", () =>
Effect.scoped(
Effect.gen(function* () {
const spawned = yield* Queue.unbounded<void>();
const gate = yield* Deferred.make<void>();
const layerSpawner = Layer.succeed(
ChildProcessSpawner.ChildProcessSpawner,
ChildProcessSpawner.make(() =>
Queue.offer(spawned, undefined).pipe(
Effect.as(makeProcess({ exitCode: Effect.never })),
),
),
);
const instance = yield* makeTestInstance({
spawnerLayer: layerSpawner,
beforeSpawn: Deferred.await(gate),
});

// The endpoint and token are readable while the spawn waits.
yield* instance.start;
assert.deepEqual(yield* instance.currentConfig, Option.some(baseConfig));
assert.equal(yield* Queue.size(spawned), 0);

yield* instance.stop().pipe(Effect.timeout("1 second"));
yield* Deferred.succeed(gate, undefined);
yield* Effect.yieldNow;
assert.equal(yield* Queue.size(spawned), 0);
assert.isTrue(Option.isNone((yield* instance.snapshot).activePid));

// A later start spawns as soon as the gate is open.
yield* instance.start;
yield* Queue.take(spawned).pipe(Effect.timeout("1 second"));
}),
),
);

it.effect("restarts when start is requested during stop teardown", () =>
Effect.scoped(
Effect.gen(function* () {
Expand Down
30 changes: 28 additions & 2 deletions apps/desktop/src/backend/DesktopBackendManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as Brand from "effect/Brand";
import * as Cause from "effect/Cause";
import * as Deferred from "effect/Deferred";
import * as Duration from "effect/Duration";
import * as Effect from "effect/Effect";
import * as Exit from "effect/Exit";
Expand Down Expand Up @@ -41,6 +42,10 @@ const DEFAULT_BACKEND_READINESS_REQUEST_TIMEOUT = Duration.seconds(1);
// and a busy one needs a few seconds to stop every provider session.
const DEFAULT_BACKEND_TERMINATE_GRACE = Duration.seconds(5);
const DEFAULT_BACKEND_OUTPUT_DRAIN_TIMEOUT = Duration.seconds(5);
const STOPPED_BEFORE_SPAWN: BackendProcessExit = {
code: Option.none(),
reason: "stopped before spawn",
};
const BACKEND_READINESS_PATH = "/.well-known/t3/environment";
const { logWarning: logBackendProcessWarning } =
DesktopObservability.makeComponentLogger("desktop-backend-process");
Expand Down Expand Up @@ -241,6 +246,11 @@ export interface BackendInstanceSpec {
// between "fired onReady" and "currentConfig already advanced".
readonly onReady?: (httpBaseUrl: URL) => Effect.Effect<void>;
readonly onShutdown?: () => Effect.Effect<void>;
// Wait after publishing config so preload can read credentials before spawn.
readonly beforeSpawn?: Effect.Effect<void>;
// Fired once when a fatal or bounded preflight failure has exhausted its
// retries. Returns true when the callback changed configuration and the
// manager should resolve once more; false stops the failed instance.
readonly onPreflightFailed?: (failure: PreflightFailure) => Effect.Effect<boolean>;
readonly onStateDirOwned?: () => Effect.Effect<void>;
}
Expand Down Expand Up @@ -657,6 +667,20 @@ export const makeBackendInstance = Effect.fn("makeBackendInstance")(function* (
});
});

// Stop must release the spawn gate without starting the stopped run.
const awaitBeforeSpawn = (runScope: Scope.Scope): Effect.Effect<boolean> => {
const beforeSpawn = spec.beforeSpawn;
if (beforeSpawn === undefined) return Effect.succeed(true);
return Effect.gen(function* () {
const stopped = yield* Deferred.make<void>();
yield* Scope.addFinalizer(runScope, Deferred.succeed(stopped, undefined));
return yield* Effect.raceFirst(
beforeSpawn.pipe(Effect.as(true)),
Deferred.await(stopped).pipe(Effect.as(false)),
);
});
};

const start: Effect.Effect<void> = Effect.suspend(() =>
mutex.withPermits(1)(
Effect.gen(function* () {
Expand Down Expand Up @@ -868,7 +892,7 @@ export const makeBackendInstance = Effect.fn("makeBackendInstance")(function* (
);
});

const program = runBackendProcess({
const spawnProcess = runBackendProcess({
...config.value,
desktopTelemetryStream: desktopTelemetryPublisher.encoded,
desktopBrowserStream: desktopBrowserHost.events,
Expand Down Expand Up @@ -931,7 +955,9 @@ export const makeBackendInstance = Effect.fn("makeBackendInstance")(function* (
},
),
onOutput: (streamName, chunk) => backendOutputLog.writeOutputChunk(streamName, chunk),
}).pipe(
});
const program = awaitBeforeSpawn(runScope).pipe(
Effect.flatMap((spawn) => (spawn ? spawnProcess : Effect.succeed(STOPPED_BEFORE_SPAWN))),
Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner),
Effect.provideService(HttpClient.HttpClient, httpClient),
Scope.provide(runScope),
Expand Down
5 changes: 5 additions & 0 deletions apps/desktop/src/backend/DesktopBackendPool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ChildProcessSpawner } from "effect/process";

import * as DesktopObservability from "../app/DesktopObservability.ts";
import * as DesktopAppSettings from "../settings/DesktopAppSettings.ts";
import * as DesktopShellEnvironment from "../shell/DesktopShellEnvironment.ts";
import * as DesktopTelemetryPublisher from "../telemetry/DesktopTelemetryPublisher.ts";
import * as DesktopBrowserHost from "../preview/DesktopBrowserHost.ts";
import * as ElectronDialog from "../electron/ElectronDialog.ts";
Expand Down Expand Up @@ -85,6 +86,10 @@ function layerPool(labelRef: Ref.Ref<string>): Layer.Layer<DesktopBackendPool.De
currentBootstrapToken: Effect.die("unexpected bootstrap token read"),
} satisfies DesktopBackendConfiguration.DesktopBackendConfiguration["Service"]),
DesktopAppSettings.layerTest(),
Layer.succeed(DesktopShellEnvironment.DesktopShellEnvironment, {
installIntoProcess: Effect.succeed(true),
secretStorageReady: Effect.void,
}),
DesktopWslEnvironment.layerTest(),
ElectronDialog.layer,
ElectronApp.layer,
Expand Down
Loading
Loading