项目地址:https://github.com/duruoxian/ocs (MIT,单文件 Python,零依赖)
缘起:历史会话太难找了
我日常用 opencode 写代码,它什么都好,就是回到旧会话特别费劲。官方的 opencode session list 只列当前目录的会话,信息只有 ID、标题和时间;想找回“上周二在某个项目里聊过的那个方案”,基本靠考古。
而在 ZCode 里,历史会话是一等公民:按项目分组、能搜索、有预览、点一下就切回去。于是我决定自己给 opencode 补上这一块,做一个终端里的、和 ZCode 一样顺手的会话选择器 —— ocs。

想要的效果
- 打开就跑出一个列表:按项目分组,组内按时间倒序,一眼看到哪个项目最近在忙什么
- 搜索要能搜内容:标题是 AI 起的不一定记得住,直接输“安装”就能把聊过安装的会话全捞出来
- 右侧实时预览:会话详情、我提过的问题,光标移动到哪就显示哪
- 会话内容折叠着看:默认只显示我提过的问题(一条一行),点击某条提问,才展开这一条的 AI 回答,再点收起
- 回车直接切回去,opencode 退出后自动回到列表继续挑
- 日常管理:重命名、批量删除、分叉继续、复制会话 ID

实现里的几个有意思的点
1. 数据:直接读 opencode 的 SQLite
opencode 把所有会话存在 ~/.local/share/opencode/opencode.db(WAL 模式)。ocs 以只读方式连上去(file:...?mode=ro),把 session / message / part 三张表里的标题、目录、时间、token、费用、消息正文全部读出来。不打补丁、不装插件,opencode 升级也不影响(重命名是唯一一次写:直接 UPDATE session SET title,因为官方没有改名的 CLI)。
2. 界面:单个 fzf 实例 + execute/reload
整个 UI 就是一个 fzf:列表是菜单,右侧 --preview 是详情,所有按键通过 --bind ... execute(ocs --xxx {2})+reload(...) 回调回自己。这样所有操作都在界面内完成——重命名、删除、进会话,界面不闪回终端、筛选词不丢。对话视图也是同一个 fzf:按 → 把列表“换页”成消息列表,--track 让光标在刷新后保持跟随,点击消息行展开/收起该条的 AI 回答(展开状态记在状态文件里)。
3. 最好玩的一块:运行时把鼠标“让”给终端
这个需求是自己用着用着逼出来的:平时要能点击列表选会话;选中文字时要能拖动选字、右键弹复制菜单,而且都不想按 Shift。
问题在于:终端里鼠标同一时刻只能有一个主人。程序开启了鼠标跟踪(1000/1002/1006 模式)后,所有拖动和右键都会送给程序,终端自己就不做选区、也不弹菜单;想选字只能按 Shift 绕过——这是所有终端的老规矩。
但有个破绽:鼠标归属是程序用转义序列声明的,而 Konsole 是实时解析这些序列的。所以 ocs 做了件事:
MOUSE_OFF = "\033[?1000l\033[?1002l\033[?1006l" # 鼠标归终端
MOUSE_ON = "\033[?1000h\033[?1002h\033[?1006h" # 鼠标归程序
把 MOUSE_OFF 写进 /dev/tty,Konsole 立刻把鼠标交还给终端——fzf 毫无感知、界面纹丝不动;此时拖动就是选字、右键就是「复制」菜单。再写入 MOUSE_ON 就切回“能点列表”的模式。绑定成两个动作:
- 右键一下(或
F8)→ 进入选字模式; - 再按
F8→ 切回点击模式。
于是三个愿望同时成立:平时单击/双击/滚轮都好使;要复制时右键一下,就和普通终端一样了,全程不用碰 Shift。
4. 一些踩过的坑(给同样折腾终端的朋友)
- 别用 F2 当功能键:Konsole 的
linux键盘映射表里 F1–F5 发的是 Linux 控制台序列(ESC[[B),现代程序(fzf)根本不识别,尾字节还会漏进搜索框;F6–F12 才是标准序列。 - fzf 的
reload会把光标弹回第一行——每次点击后刷新列表会把“点中”的选择撤销掉,加--track才解决。 - 子进程量不到终端尺寸:
reload/execute子进程的 stdout 是管道,shutil.get_terminal_size()拿不到真实宽度,会导致列表错位;直接向/dev/tty要TIOCGWINSZ才准。 - 颜色要看主题:我的终端主题把 cyan 槽位定义成了纯绿 (0,255,0),所有“青色”高亮都变成刺眼的绿色——现在统一用蓝色 + 品红。
5. 验证方式:给终端 TUI 做“真鼠标”回归测试
这些交互都跟鼠标有关,靠肉眼在山寨环境里点是不靠谱的。所以我在 Xvfb(无头 X 服务器)里跑真的 Konsole + 真的鼠标事件(xdotool),截图比对、读剪贴板验证:拖动是否产生选区、右键菜单里的「复制」是否可用、剪贴板内容是否正确、点击是否选中了目标行……全流程自动化。凡是“应该能用”的功能,都是在这种环境里点过一遍才敢说它行。
安装与使用
git clone https://github.com/duruoxian/ocs.git
cd ocs && ./install.sh # 装到 ~/.local/bin/ocs
ocs # 打开会话列表
依赖只有 Python 3 和 fzf;数据来自你已经用过的 opencode。
日常就记住三件事:
- 打开
ocs,打字搜索,回车切回; - 按
→进对话视图,点问题看 AI 回答,←回来; - 要复制文字:右键一下(或按
F8),拖选、右键复制,再F8切回。
项目在 https://github.com/duruoxian/ocs ,MIT 协议,欢迎来提 issue 或者点个 star ⭐