diff --git a/emrg/server/evolution_prompt.md b/emrg/server/evolution_prompt.md index 56b439b..3ce0e1b 100644 --- a/emrg/server/evolution_prompt.md +++ b/emrg/server/evolution_prompt.md @@ -383,6 +383,8 @@ When reading rants, follow these rules: > - ConnManager open/close/get (#624 GUI 多会话 rant 2026-08-10T15:07:19 P2 slice 2:新模块 `emrg/gui/conn-manager.js`——connManager=daemon 生命周期唯一 owner + 每会话一条独立 DaemonClient 连接(对齐 TUI 多开:每 TUI 一条连接;会话间天然隔离无事件路由);`open(sid, projectPath)`=引导 client `ensureConnected()`(spawn 或直连后关闭)→ 新 DaemonClient `ensureConnected({skipStart})` → `resume_session(sid, cwd=projectPath)` 自动订阅 → 存储,已打开 sid 复用不重复建连;`close(sid)`/`get(sid)`/`all()`/`closeAll()`;main.js 未改线(单会话无回归目标随 rewire 片落);+5 测试 conn-manager、GUI 111→116 三文档同步;680 pytest 全绿;rant 分阶段 P1-P6,P2 剩余=main.js rewire + restart recovery,P3-P6 待续) ✅ > - DaemonClient per-connection delta batching (#626 GUI 多会话 rant 2026-08-10T15:07:19 P2 slice 3:delta 批量从 main.js 共享态移入**每条 DaemonClient 实例**——构造参数 `deltaBatchMs`(默认 0=每帧即时发,既有行为不变);`_deltaBuf/_deltaTimer/_flushDeltaBuf()` 实例化,`message_delta` 帧入缓冲按 batch 合并成 `chunks` 形状一次发出(与 G122 16ms 同形),终态(done/error/cancelled)与断连前强制冲刷保序(rant 14:11 孤儿节点教训);多会话各自独立缓冲互不干扰;+6 测试 daemon_client 31→37、GUI 118→124 三文档同步;680 pytest 全绿) ✅ > - ConnManager daemon restart recovery (#627 GUI 多会话 rant 2026-08-10T15:07:19 P2 slice 4:短窗口内**所有**打开会话连接同时断 → 判定 daemon 重启 → `recoverAll()` 全量恢复——close 全部 → 按 `open()` 序列(引导→skipStart→resume_session 重订阅)逐会话重开,单会话失败跳过不阻塞其余;单条断 → 不触发全量恢复(留给后续片独立退避);`_restartDetected()` 检查 `_disconnects`(sid→最近断连时间戳)全部落在 `restartWindowMs`(默认 1000ms 可配)窗口内;`_recovering` 守卫防 close→disconnect→recoverAll 递归;+3 测试 conn-manager 5→8(全断自动恢复/单断负态/recoverAll 重开重订阅含 stale 连接排除)、GUI 121→127(合并 #626 后 124→127 文档计数冲突化解)三文档同步;680 pytest 全绿;P2 剩余=main.js rewire + single-conn backoff,P3-P6 待续) ✅ +> - GUI main.js ConnManager rewire (#629 GUI 多会话 rant 2026-08-10T15:07:19 P2 收官:main.js 全量改走 ConnManager——conn-manager `ensureDaemon()` 保留 daemon 级连接(ping/list_sessions/set_model/github_* 等非会话命令),会话连接 skipStart 不 spawn;`open({resume:false})` 供新会话(daemon 隐式订阅),失败关半开连接不泄漏,断连残留 stale 关闭重开;`onOpen`/`onRecovered` 钩子(事件桥含 recoverAll 重开路径 + 恢复后 sessions/pong/status 刷新);`close()` 标 `_intentionalClose` 抑制断线横幅 + 不触发重启判定;**单连接独立退避**(N 会话单条断 → 退避重开该会话);daemon_client G65 自有流锁移入实例(own done/timeout/session-busy/own cancelled/断连释放);main.js 删全局 client/ownStream/deltaBuf,IPC 全走 activeConn/requireConn/openSession,sendMessage 自动 open,switchSession 切走关旧连接,cancel 发激活连接,事件桥附带 sid;+15 测试(dc 37→43、cm 8→17)GUI 127→142 三文档同步;680 pytest 全绿;P2 完成) ✅ +> - GUI renderer per-session chat isolation (#630 GUI 多会话 rant 2026-08-10T15:07:19 P3 slice 0:renderer 会话级聊天状态隔离——chat.js `sessionState` Map(sid→{groupNodes,toolRows,doneRids},sid=null 旧版单会话桶零回归)+ 全部 handler 可选 sid(handleDelta/handleDone/handleToolStart/handleToolEnd/clearTyping/clear/addSystemMessage/addUserMessage/createAssistantNode)+ 容器路由 API `registerContainer(sid,el)`/`unregisterContainer(sid)`/`chatContainer(sid)`(未注册回退默认 #chat-view,P4 openSessions 用)+ `groupNodesFor`/`toolRowsFor` 访问器;app.js handleEvent 透传 `evt.sid`(#629 事件桥附带),disconnected 按 sid 隔离分组清理+工具行失败标记;+4 测试 renderer.smoke 32→36(两会话同 rid 隔离/done 只清本会话/clearTyping 作用域/容器路由回退);GUI 142→146 三文档同步(#629 合并计数冲突解到 146);680 pytest 全绿;P3 剩余=chat-view 容器 + sessionsBySid + 事件按 sid 路由,P4-P6 待续) ✅ #### 2.2 Latest GitHub code changes