Why
深度审计确认(TUI 侧确认级内存泄露):路由组件的 event.on 返回的退订函数被丢弃,handler 永久驻留 SDKProvider 的 app 级 eventHandlers: Set(packages/tui/src/context/sdk.tsx:49,进程生命周期):
packages/tui/src/routes/session/index.tsx:327、:357——message.part.updated / session.status 各 1 个,闭包持有 route(含 sessionID)、local、dialog、kv;每次 session ↔ home 路由往返 +2
packages/tui/src/component/prompt/index.tsx:234——tui.prompt.append 1 个,闭包持有 opentui input(editor 节点树)与 renderer,单条 retention 显著更大;布局卸载/重挂载累积
旧 handler 对每个后续事件仍重复执行(sessionID 过滤空转),与正确 handler 并存。
Scope
packages/tui/src/routes/session/index.tsx:327,357
packages/tui/src/component/prompt/index.tsx:234
Approach
- 每个
event.on(...) 的返回退订函数包进 SolidJS onCleanup(两文件内已有 onCleanup 用法先例,如 session/index.tsx:212、prompt/index.tsx:310/633)
- 不引入新抽象;如后续同类点多,可再评估
useEvent 自动清理 hook(不在本 issue 范围)
Acceptance
- 测试(fixture 或单测):挂载 → 卸载 session 路由 / prompt 组件后,
eventHandlers Set 尺寸回落
- 既有 TUI 相关测试全绿(含
test/cli/cmd/tui/sync-fixture.tsx 体系)
Why
深度审计确认(TUI 侧确认级内存泄露):路由组件的
event.on返回的退订函数被丢弃,handler 永久驻留SDKProvider的 app 级eventHandlers: Set(packages/tui/src/context/sdk.tsx:49,进程生命周期):packages/tui/src/routes/session/index.tsx:327、:357——message.part.updated/session.status各 1 个,闭包持有route(含 sessionID)、local、dialog、kv;每次 session ↔ home 路由往返 +2packages/tui/src/component/prompt/index.tsx:234——tui.prompt.append1 个,闭包持有 opentuiinput(editor 节点树)与renderer,单条 retention 显著更大;布局卸载/重挂载累积旧 handler 对每个后续事件仍重复执行(sessionID 过滤空转),与正确 handler 并存。
Scope
packages/tui/src/routes/session/index.tsx:327,357packages/tui/src/component/prompt/index.tsx:234Approach
event.on(...)的返回退订函数包进 SolidJSonCleanup(两文件内已有onCleanup用法先例,如 session/index.tsx:212、prompt/index.tsx:310/633)useEvent自动清理 hook(不在本 issue 范围)Acceptance
eventHandlersSet 尺寸回落test/cli/cmd/tui/sync-fixture.tsx体系)