hermes-agent/apps/desktop/scripts
brooklyn! 3139a30e52
perf(desktop): multi-tile grids stop lagging — evict leaked session states, index lineage aliases, split the turn journal (#83133)
* fix(desktop): evict settled session states nothing on screen references

Closing a tile never removed its runtime's entry from $sessionStates, so
every tile ever closed parked its full transcript in the map for the life
of the process. Each leftover entry taxes every subsequent stream flush —
the map is spread-copied per delta and the busy/attention/draft projections
walk every entry per publish — so the app got slower the longer it ran,
which users read as "I need to clean my sessions/dbs".

Publish now evicts a settling state when no tile and not the primary view
holds its runtime (transition side effects still fire, so the settle keeps
its unread dot), and closing a tile drops an already-settled state on the
spot. Busy and needs-input states stay: background turns feed the sidebar
dots, and a first publish always lands because a resume can publish a beat
before the surface binds the runtime.

16 tiles streaming in a 2x2 grid with a day's worth of closed-tile residue:
worst-second 34 -> 58 fps, p99 frame 90 -> 28 ms, longtasks 37 -> 0.

* perf(desktop): index lineage aliases per sessions-list reference

lineageAliases scanned the whole recents list per call, and it is called
per cached session state per status projection per message delta — with a
populated sessions DB and a few busy sessions that multiplied out to
millions of row checks a second during streaming. Build the alias index
once per list reference (the list is replaced wholesale, never mutated)
and look aliases up in O(1).

* perf(desktop): journal each in-flight turn under its own storage key

The v1 journal kept every session's tail in one localStorage key, so each
throttled write re-parsed and re-stringified EVERY busy session's snapshot
— a grid of concurrent streams turned that into a whole-store JSON round
trip dozens of times a second, all on the main thread. Per-session keys
make a write O(own tail) no matter how many other sessions are streaming.
A v1 store migrates on first touch; expired/overflow crash residue is
pruned once per renderer.

* perf(desktop): stress the multitab scenario across grid/streaming/DB axes

The one-stack multitab run hid every cost this round of fixes removed: it
drove hook.publish (store only — no journal, no wiring cache), with an
empty recents list and no closed-tile residue. Streaming now routes through
hook.update (the real gateway write path), and the scenario grows axes for
the workloads users actually hit: --zones splits tiles across visible grid
zones, --streaming caps how many sessions are mid-turn (zone leaders
first), --sessions seeds a lived-in recents list, --dead models settled
sessions no surface references. launch.mjs pins HERMES_DESKTOP_CDP_PORT so
a non-default --port survives the app's own dev-CDP flag.
2026-08-10 10:45:43 +00:00
..
perf perf(desktop): multi-tile grids stop lagging — evict leaked session states, index lineage aliases, split the turn journal (#83133) 2026-08-10 10:45:43 +00:00
.gitignore
…
after-pack.mjs
…
assert-dist-built.mjs fix(desktop): keep react-router in one runtime chunk 2026-08-10 02:04:47 -04:00
assert-dist-built.test.mjs fix(desktop): keep react-router in one runtime chunk 2026-08-10 02:04:47 -04:00
assert-root-install.mjs
…
before-build.mjs
…
before-pack.mjs build(desktop): stage get-windows like node-pty 2026-08-08 12:17:50 -05:00
before-pack.test.mjs
…
bundle-electron-main.mjs build(desktop): stage get-windows like node-pty 2026-08-08 12:17:50 -05:00
click-session.mjs
…
dev-mock.mjs
…
dev-no-hmr.mjs
…
diag-code-live.mjs perf(desktop): 60fps sash drag on real sessions — height-gate the RO pins 2026-07-27 01:07:48 -05:00
diag-drag-churn.mjs perf(desktop): stop every zone subscribing to the whole layout tree 2026-07-26 16:53:20 -05:00
diag-drag-trace.mjs perf(desktop): share one ResizeObserver instead of one per consumer 2026-07-26 19:56:55 -05:00
diag-jump.mjs
…
diag-key-latency.mjs perf(desktop): 60fps sash drag on real sessions — height-gate the RO pins 2026-07-27 01:07:48 -05:00
diag-live-state.mjs perf(desktop): 60fps sash drag on real sessions — height-gate the RO pins 2026-07-27 01:07:48 -05:00
diag-overlay-ab.mjs chore: overlay churn measurement probes (sweep + median A/B) 2026-07-28 20:26:58 -05:00
diag-overlay-churn.mjs chore: CDP probe for overlay render-churn measurement 2026-07-28 19:03:17 -05:00
diag-overlay-full.mjs chore: full overlay render-churn measurement probe 2026-07-28 20:04:21 -05:00
diag-overlay-sweep.mjs perf(desktop): memoize sidebar rows + status dots + artifact cells 2026-07-28 20:23:10 -05:00
diag-real-loop.mjs perf(desktop): 60fps sash drag on real sessions — height-gate the RO pins 2026-07-27 01:07:48 -05:00
diag-ro-storm.mjs perf(desktop): share one ResizeObserver instead of one per consumer 2026-07-26 19:56:55 -05:00
diag-scroll-reset.mjs
…
diag-sidebar-dom.mjs perf(desktop): 60fps sash drag on real sessions — height-gate the RO pins 2026-07-27 01:07:48 -05:00
diag-switch-autopsy.mjs perf(desktop): don't backfill the transcript while its thread streams 2026-07-27 01:14:29 -05:00
diag-switch-trace.mjs perf(desktop): 60fps sash drag on real sessions — height-gate the RO pins 2026-07-27 01:07:48 -05:00
eval.mjs feat(desktop): on by default for dev-server runs 2026-07-27 23:52:33 -05:00
gen-share-codes.ts
…
live-drive.mjs perf(desktop): don't backfill the transcript while its thread streams 2026-07-27 01:14:29 -05:00
notarize-artifact.mjs
…
notarize.mjs
…
patch-electron-builder-mac-binary.mjs
…
probe-command-palette.mjs perf(desktop): make ⌘K cost nothing until it opens 2026-07-30 03:01:05 -05:00
probe-model-picker.mjs
…
probe-renderer.mjs
…
probe-thread.mjs
…
profile-model-picker.mjs
…
profile-typing-lag.md
…
rebuild-native.mjs
…
reload-renderer.mjs
…
reload.mjs
…
run-electron-builder.mjs
…
set-exe-identity.mjs
…
stage-native-deps.mjs fix(desktop): rebuild get-windows when its win32 binding is missing 2026-08-08 21:23:20 -05:00
stage-native-deps.test.mjs fix(desktop): rebuild get-windows when its win32 binding is missing 2026-08-08 21:23:20 -05:00
test-desktop.mjs
…
utils.mjs
…
write-build-stamp.mjs
…
write-build-stamp.test.mjs
…