dsh-chat-unread · 会话列表「标记为未读」
给 DeepSeek Harness(DSH)桌面端左侧会话列表补一个手动标记未读:标记后行首亮一个蓝点,会话「…」菜单里可随时切换
「标记为未读 / 标记为已读」,打开该会话时自动清除。标记保存在宿主账本($DSH_HOME/chat-unread.json),
应用重启后仍然在。
An unread-mark plugin for the DeepSeek Harness (DSH) desktop sidebar session list. Marks live in a host-side ledger, survive restarts, and clear when the session is opened.
- 运行时依赖:无(纯 ESM + 手写浏览器 bundle,零构建)
- 无网络请求、无外部进程、无文件读写之外的副作用
- 兼容性:DSH Desktop 0.2.1-rc.2 实测通过(宿主 + 浏览器半区)
功能
| 位置 | 行为 |
|---|---|
| 会话行行首(主状态为「闲置」时) | 未读时显示蓝色小圆点 |
| 会话行悬浮(鼠标移上去) | 出现一个小圆点按钮:点击即切换未读/已读 |
| 会话行「…」菜单 | 多一项「标记为未读」/「标记为已读」,点击切换 |
| 悬浮卡(停留在会话行 0.8 秒) | 未读时多一行「● 已标记为未读」 |
| 打开会话 | 从别的会话切入该会话时,自动清掉它的未读 |
说明:
- 官方会话行在「运行中 / 刚跑完 / 等待回答」时会把行首让给状态点,这时蓝点暂时让位给状态点; 悬浮按钮、菜单、悬浮卡仍然可用,未读状态不会丢。
- 手动标记当前正在看的会话不会立刻消失(避免标记动作被自动清除吞掉),切走再切回、或从菜单点 「标记为已读」即可清除。
- 页面刷新、应用重启后标记仍在;多开窗口会在窗口重新可见 / 切换会话时刷新账本。
安装
方式一:本地目录(推荐,开发态)
git clone https://github.com/nmglyx-hub/dsh-chat-unread.git
CLI="/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh"
"$CLI" plugin --profile desktop add link:"$PWD/dsh-chat-unread"
宿主半区由 DSH 的 HMR 热加载;浏览器半区通过 /plugins/events 的 graph 帧自动挂载。
实测:安装后无需重启应用(宿主路由与浏览器 bundle 自动生效);若界面未出现,按 ⌘R 刷新一次即可。
方式二:从 GitHub 直接装
dsh plugin --profile desktop add github:nmglyx-hub/dsh-chat-unread
该写法依赖 pnpm 的 git 依赖解析;如果本机 CLI 的
github:简写不可用,请用方式一 clone 后link:安装。
卸载:
"$CLI" plugin --profile desktop remove dsh-chat-unread
账本文件不会被自动删除;不需要时可手动删除 $DSH_HOME/chat-unread.json(默认 ~/.dsh/chat-unread.json)。
数据与安全
- 账本:
$DSH_HOME/chat-unread.json,结构{ version, updatedAt, ids: [...] },只存会话 id,不存标题、正文或任何案件内容。 - 接口:
/api/chat-unread/*(list/mark/clear/toggle/ping/hello)。 只接受回环地址 + 同源请求;sessionId只接受[A-Za-z0-9._:-]{1,200};账本最多 5000 条。 - 宿主路由不读业务文件、不调用外部程序、不发起外网请求;没有删除会话的能力。
- 浏览器半区只通过官方扩展槽渲染,不读写别的插件的 DOM、不新增全局样式之外的元素。
自检 / 测试
npm install # 仅测试用(react / react-dom)
npm test # 宿主 21 项 + 浏览器 21 项
运行中实例的自检(端口换成当前 DSH 实际端口):
curl -s http://127.0.0.1:57197/api/chat-unread/ping
ping 返回里的 clientGraph.registered 表示浏览器 bundle 已进客户端模块表;
clientHello 是浏览器半区实际加载后回传的自检(含四个扩展槽的注册状态),可用来确认 UI 真的跑起来了。
实现
| 半边 | 文件 | 职责 |
|---|---|---|
| 宿主 | lib/index.js |
/api/chat-unread/*:list / mark / clear / toggle / ping / hello;账本原子落盘到 $DSH_HOME/chat-unread.json |
| 浏览器 | lib/client.js |
手写 window.__ModuleLoader__ bundle:订阅 ctx.sessions.list 判断主视图切换;向 sidebar.session.row.leading、sidebar.session.row.hover、sidebar.workspaces.session.row.action、sidebar.workspaces.session.menu.item 四个官方扩展槽注册组件 |
| 清单 | package.json / cordis.patch.yml |
dsh.bundle.patch + dsh.client(platform: web)声明,双面插件随 profile 装载 |
设计取舍
- 不用浏览器 localStorage:DSH 桌面端每次启动以
--port 0申请随机端口,页面 origin 随端口变化, 浏览器存储会在重启后失效;「标记未读」本身是为了下次回来看,所以改为宿主账本,跨重启保留。 - 只做标记未读:不附带删除会话、外部程序打开等能力,减少误操作面;卸载即恢复官方外观。
- 与同类插件的差异主要在持久化位置与功能边界;如果你需要角标统计、置顶、标签等更多能力,可另配同类插件。
License
MIT
No comments yet. Be the first to write one.