emrg: GUI open-sessions sidebar + gui_state restore — P4 slice 2 (GUI multi-session rant P4) - #639
Conversation
… multi-session rant P4)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260810-180149 (author). P4 slice 2: open-sessions sidebar + gui_state restore; 167 GUI (163+4) + 680 pytest green.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260810-181309. Reviewed the full diff: restoreOpenSessions (cap-20, stale-entry skip + re-persist, activeSid fallback, window-title sync), broadcastOpenSessions on all mutations, sidebar renderOpenSessions with active highlight + right-click menu (close-keep-data/rename/delete), busy-guard on closing the active session, zh/en i18n, bounded CSS. Verified locally: node --check clean; GUI 167/167 (163+4); pytest 680/680 incl. doc-count guard.
|
I tested this PR (P4 slice 2 — open-sessions sidebar + gui_state restore) end-to-end and the code review came back clean. |
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 20260810-181428
Re-verified on head c8a4067: GUI suite 167/167 (renderer smoke 50 — open_sessions event renders project/title + active highlight; close active session switches to remaining + container released; close bg session keeps active pointer; boot adopts restored activeSid without switchSession round-trip; mock querySelectorAll DFS + classList.toggle force fidelity), 680 pytest green, doc-count guard passes (167 = 43+17+22+50+15+7+3+3+7), CLI OK, node --check clean.
…640) Co-authored-by: EMRG Evolution <emrg@argszero.dev>
Summary
P4 slice 2 of the GUI multi-session rant (2026-08-10T15:07:19): the open-sessions sidebar + boot restore — the other half of P4 after slice 1 (#637, open-sessions state + gui_state.json persistence).
Changes
emrg/gui/main.js
restoreOpenSessions(sessions)— on init: readgui_state.json, re-open valid entries (cap 20, resume + re-subscribe), skip stale entries (removed + re-persisted), restoreactiveSid(fallback: most recent), window-title syncbroadcastOpenSessions()— pushesopen_sessionsevents to the renderer on every mutation (open/touch/activate/close/delete/new) — the sidebar's live data sourceopen_sessions+active_sidso the renderer adopts the restored active session without an extra switchSession IPC round-tripemrg/gui/renderer
renderOpenSessions(list): cross-project open-session section at the top of the sidebar (项目名 / 会话标题, lastActive desc from main, active highlight, click → switch, right-click → close/rename/delete);highlightnow also covers open-session itemsstate.openSessions; handlesopen_sessionsevents;closeOpenSession(sid)(disconnect + remove container + keep disk data; closing the active session switches to the most recent remaining open session, else new);showOpenSessionsMenu(关闭保留数据 / rename / delete with confirm)#open-sessionsnav + label above the conversation listsidebar.openSessions/noOpenSessions/openSessionOf/app.closeSession/app.closeFailedtest/renderer.smoke.test.js — +4 tests (open_sessions event renders project/title + active highlight; close active session → switch to remaining + container released; close bg session → no switch; boot adopts restored activeSid). Mock upgrades:
querySelectorAllDFS for class selectors (highlight),classList.togglehonorsforce(faithful DOM semantics). GUI 163→167 (renderer smoke 46→50); README/README.cn/Agent.md synced; 680 pytest green; node --check clean.Verification
node --checkclean on all touched JS