Memory
dsh-tui-session-manager
BoweiDuan/dsh-tui-session-manager · ★ 1
Session manager for dsh-TUI: a /sessions scene to browse, filter and truly delete saved sessions, including the state leftovers the host delete path leaves behind.
README body is shown in Chinese.
Manifest details
安装
dsh plugin --profile web add 'github:BoweiDuan/dsh-tui-session-manager#c6ebddb1a9108af2e6c6bd4b68a73c40ffb743ee'GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
Table of contents
dsh-TUI · 一个为 dsh-TUI 生态打造的插件
给 dsh-TUI 的会话管理器:一条 /sessions 命令打开全屏面板,按工作区分组浏览、
过滤、多选,然后真正删除保存的会话 —— 并把宿主删除路径留下的状态残留一并清掉。
A session manager for dsh-TUI: /sessions opens a full-screen browser grouped by
workspace, with filtering, multi-select and real deletion — including the state
leftovers the host's own delete path does not touch.
为什么需要它 / Why
dsh-TUI 0.11.x 的适配层其实已经实现了真正的删除(channel.deleteSession(id):
递归删除会话日志目录、清 resume 标记、last-used.json 与 agent-view 记录),
但没有任何 UI 调用它 —— 命令表、/resume 选择器、工作区菜单里都没有入口。
缺的是入口,不是能力。本插件不重写删除逻辑,只补上入口。
两件常被问到的事,这里一次说清:
- 列表里的空会话从哪来? DSH 的「新建会话」是立即落盘的:TUI 进程启动、
切换工作区(
switchWorkspace→newSession)或/new之后,会话日志就已经存在。 若随后/resume到别处或直接退出,它就留成一个只有 4 条元数据帧、0 条消息的 空壳,标题回退成目录名。按e可一键筛出它们。 - 这些空壳占空间吗? 不占。每个约 312~466 B,宿主列表还有
revision缓存。 真正占空间的是历史调试留下的*.bak-*备份,那是另一回事。
功能 / Features
/sessions全屏管理器:按工作区分组、/实时过滤(标题 / 工作目录 / id)。e三态过滤:全部 → 只看空壳 → 隐藏空壳。- 空壳行标注体积(
empty·312B),头部显示总数、空壳数与当前视图。 - 多选批量删除(
a全选当前可见集),删除前y/n确认。 - 删除后清扫宿主不碰的四处残留,杜绝
/resume里的幽灵条目。 - 无构建、无运行时依赖、纯 ESM:装进 profile 即用。
安装 / Install
git clone https://github.com/BoweiDuan/dsh-tui-session-manager.git
dsh plugin --profile dsh-tui add ./dsh-tui-session-manager
装完重启 dsh-tui(profile 的 patchReload: live 也可能让它热加载)。卸载:
dsh plugin --profile dsh-tui remove dsh-tui-session-manager
用法 / Usage
在对话里输入:
/sessions
全屏管理器打开,对话保持干净(命令返回静默成功)。
| 按键 | 作用 |
|---|---|
↑ ↓ / k j |
移动光标 |
space / x / enter |
勾选或取消当前会话 |
a |
全选 / 全不选(仅当前可见集) |
d |
删除已勾选(先弹 y / n 确认) |
/ |
输入过滤词(匹配标题、工作目录、id) |
e |
循环过滤:全部 → 只看空壳 → 隐藏空壳 |
esc |
退出过滤 / 取消确认 / 关闭面板 |
清理空壳的标准动作:/sessions → e → a → d → y。
删除结果在底部汇总:deleted N, refused M。当前正在使用的会话会被宿主拒绝
(与宿主语义一致,不是本插件的限制)。refused 也覆盖日志已丢失的情况。
空会话判定 / Empty artifacts
只有三个条件全部满足才算空壳(保守:宁可漏掉一个,也不隐藏或误删有内容的会话):
kind !== 'subagent' // 子代理天然无人类消息,排除
&& hasPrompt === false // 宿主证明没有人类消息;日志不可读时为 true
&& bytes < 4096 // 4 条元数据帧约 312~466 B
&& title.source === 'fallback' // 标题仍是目录名回退
bytes 缺失、标题来源非 fallback、kind 无法识别 —— 一律不判为空。
判定只读宿主 channel.listSessions() 已给出的摘要字段,不读会话日志。
安全 / Safety
- 会话 id 必须匹配
^[A-Za-z0-9][A-Za-z0-9_-]*$才会被当作文件名或 map 键使用, 其它一律跳过并报告。 - 每次清扫在首次改动某个 JSON 文件前备份为
<file>.bak-sweep-<YYYYMMDD-HHMMSS>。 - 无法解析的 JSON 原样保留,不做猜测性修改。
- 清扫过程不抛异常:单步失败计入结果行,不影响其它步骤。
- 删除不可撤销(没有回收站):勾选时请看清,确认时
y是唯一入口。
兼容 / Compatibility
- dsh-TUI 0.11.x;接缝
ctx.tuiScenes(全屏场景)与ctx.commands(斜杠命令)。 - 两者都做软探测:宿主不提供时插件保持 idle,不会让启动失败。
- 场景只使用宿主注入的
props.React与props.ui,不引入自带 React (TUI 的 reconciler 只认宿主自己的 React 19 元素)。 - Node
^22.19 || >=24。
开发 / Development
npm test # node --test,无依赖、无构建
测试覆盖:命令/场景注册与注销、无声成功返回、缺接缝时保持 idle、
空壳判定的四个条件与边界、e 三态过滤、a 只作用于可见集、
id 白名单与 dryRun、以及在临时 $DSH_HOME / $DSH_TUI_HOME 上真实落盘的清扫。
结构 / Layout
index.js 插件契约(name / apply):注册 /sessions 命令与全屏场景
scene.js 全屏管理器界面 + 空壳判定(使用宿主注入的 React 与 ui kit)
sweep.js 删除后的残留清扫(支持 dryRun)
debug.js 诊断日志($DSH_TUI_HOME/session-manager.log,64 KiB 上限)
cordis.patch.yml 向 profile 插入插件行
test/ 契约测试、判定测试与清扫落盘测试
docs/design/ 设计说明
许可 / License
MIT © 2026 BoweiDuan