* feat(web): fixed session order display setting
Add a per-device "Fixed session order" toggle (default off, Settings →
Display → Sessions). When on, the session list freezes: sessions sort
by creation time only (newest first) instead of re-sorting on
activity, workspace groups stop jumping (ordered by the newest session
created inside them), and the pin-in-progress running buckets are
paused. Manual pins still float to the top; search-relevance ordering
is unchanged.
- shared: SessionSummary gains an optional createdAt (toSessionSummary
copies it). Older hubs simply omit it and the web falls back to
updatedAt, degrading to the legacy activity order.
- web: sessionOrder lib (stable key + comparator), useFixedSessionOrder
localStorage hook, useSSE cache sort via ref (no EventSource teardown
on toggle), SessionList in-group/group/machine sorts plus bucket
gating, settings switch, en/zh-CN/ru strings.
- tests: sessionOrder unit, useFixedSessionOrder hook, useSSE
fixed-order cache cases, SessionList grouping cases, settings page
switch, shared createdAt passthrough.
Co-Authored-By: Claude Code <noreply@anthropic.com>
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
* fix(web): tie-break equal order keys on session id
Review follow-up: sessions created in the same instant compared as equal,
so their relative order came from the incoming array order — which the
hub may derive from activity, making tied sessions visibly swap after
every refetch. Tie-break on session id to make the comparator a total
order. Two tests cover the comparator and the refetch-stability view.
Co-Authored-By: Claude Code <noreply@anthropic.com>
* fix(web): tie-break equal group creation instants on the group key
Review follow-up: the directory- and machine-level sorts compared only
the groups' latest creation instants, so groups created in the same
instant followed the incoming array order and could shuffle after every
refetch. Route both fixed-order group sorts through a shared
compareDescWithKeyTiebreak helper that falls back to the group's stable
key (directory groups: machine::path key; machine groups: machineId).
Test covers both incoming orders of two tied groups.
Co-Authored-By: Claude Code <noreply@anthropic.com>
---------
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: HAPI <noreply@hapi.run>