安装
在 DeepSeek Harness 里通过 dsh-market 安装
dsh plugin --profile web add dshmarket
或使用命令行
dsh plugin --profile web add dsh-session-colorful-unread-pin-jobs
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络。请先审阅源码,并尽量锁定 commit(github:owner/repo#sha)。
截图
README
中文 | English
用颜色一眼看清侧栏哪些会话还有没看过的产出、哪些已经跑完。 会话标题按状态染色:未读(模型运行中=蓝,已跑完=绿)、置顶(黄,读 DSH 官方的置顶集合);两种状态并存时按「置顶黄在左 → 未读蓝/绿在右」合成一条渐变。颜色由当前主题的品牌色推导,自动适配明暗主题与黑白主题。
置顶、归档与排序是 DSH 官方能力(0.1.7-alpha.2 起内置):菜单、pin 图标、置顶集合与置顶优先排序都由官方提供,本插件不重复实现,只读取官方置顶集合用于染色。插件也不再改写官方 bundle:菜单走官方插槽,染色走会话行 DOM,卸载即净。
效果



以上为界面示意图(由
assets/mockups/generate.mjs生成,色值取自 DSH 主题 token),非真实截图,不含任何用户会话数据。
亮点
| 状态 | 颜色 | 触发条件 |
|---|---|---|
| 未读 · 运行中 | 品牌蓝渐变 | 模型在任何会话(含当前打开的)里产出内容,且该会话仍在运行 |
| 未读 · 已完成 | 绿渐变 | 上一条的前提消失(会话回到空闲)——任务做完了 |
| 置顶 | 黄渐变 | 官方置顶(会话行「…」→「置顶会话」);插件只读官方置顶集合 |
| 两者并存 | 黄 → 蓝/绿 | 按语义定序合成:置顶色恒在最左、未读色在最右 |
- 不需要盯着看:任务跑完的会话会在侧栏自己由蓝转绿,切换窗口时一眼扫到哪几个会话已经出结果。
- 不打扰、不丢状态:未读集合由服务端持久化,刷新页面、重启进程都保留。
- 纯增量:不改写官方 bundle、不接管官方行为,只给会话行加类、给标题上色;卸载即净。
功能
- 自动未读——模型在**任何会话(含当前打开的)**里产出内容的那一刻(
assistant/chunk内容块 /assistant/message/tool/result白名单),该会话自动染上未读渐变色。颜色区分任务状态:仍在运行=品牌蓝,已跑完回到空闲=绿色(运行态读会话列表 store 的running标志,store 一变即重判)。 - 清除时机——打开、停留、发送消息都不清除标记;把当前会话从 A 主动切到 B 时清除 A 的标记;身处当前会话时再点一次该会话行也清除(与原生「选中=确认」语义一致)。两种情况都是本地立即摘除 + 服务端持久化。
- 标题状态染色(颜色合成器)——所有观感收敛到一条代码路径:行状态 → 锚点色序列 → 绘制。语义色序自左向右:置顶=黄(最左)→ 未读=蓝(运行中)/绿(完成,最右)。单独一种状态=整条该色系渐变(未读按主题品牌色推导同族双色;黑白主题自动退化;所有端色做背景对比度守卫);两种并存按分段模板展开(纯色区 + 段间过渡)。渐变由行内样式画在标题元素上,React 重渲染不会重写、无需补绘。渐变色标随实际文字宽自适应:短文字把色标按文字宽压成 px,长文字按容器宽百分比。
- 发送即清(可选,默认关)——设置里打开后,在被标记的会话里发送消息也自动摘除该标记。
- 手动标记——会话行「…」菜单新增一条「标记为未读 / 标记为已读」(经官方插槽
sidebar.workspaces.session.menu.item注册,落在官方条目之后)。 - 只读官方置顶——置顶集合来自官方
workspaces.list快照的pinnedSessionIds(归档行按官方语义排除);插件不写置顶、不做置顶排序,官方置顶行为原样保留。 - 设置分节——设置 →「会话未读」:列出全部未读会话(标题、运行中标记、会话 ID),「刷新」按钮手动更新,逐条「标记已读」,以及「发送即清」开关。
- 零 bundle 改写——菜单与设置走官方插槽,染色靠观察会话行 DOM(
data-row-key="session:<id>"+ 标题 class 后缀_title);不再有锚点字符串替换,也不再把转换结果写回盘上的官方client.js。
安装
dsh plugin --profile web add dsh-session-colorful-unread-pin-jobs@latest
从 GitHub 安装(等价):
dsh plugin --profile web add github:enterhalf/dsh-session-colorful-unread-pin-jobs
卸载:
dsh plugin --profile web remove dsh-session-colorful-unread-pin-jobs
要求:DSH ≥ 0.1.7-alpha.2(新侧栏:官方置顶 + 官方插槽 + 行 data-row-key)。更旧的 DSH(npm latest 目前仍是 0.1.5-rc.3)请继续用本插件的 1.0.0。
卸载即净:插槽注册、路由、事件订阅、定时器、观察器全部随 fiber dispose 移除;未读集合与设置保留在 ~/.dsh/storages/dsh-session-colorful-unread-pin-jobs/,重新安装后自动恢复。
原理
- 未读数据平面(服务端持久化)——host 订阅
session/event,白名单事件落地时把非子代理会话(含当前打开)标记未读(幂等,无变化不写盘)。存储为~/.dsh/storages/dsh-session-colorful-unread-pin-jobs/unread.json(原子写、最多 2000 条 FIFO 淘汰,含clearOnSend设置)。客户端每 2 秒轮询GET /session-colorful-unread-pin-jobs/list对账(host 为权威)。 - API 平面(挂在 webServer 路由表,前缀
/session-colorful-unread-pin-jobs)——GET /list→{ ok, ids }POST /toggle{ id, unread }→{ ok, ids }GET/POST /settings→{ ok, clearOnSend }- (v1 的
/top、/active、/timestamps已随自研置顶与排序平面一起移除)
- UI 平面(官方扩展点)——
- 菜单条目:
ctx.slots.inject('sidebar.workspaces.session.menu.item')注册一条插件条目; - 设置分节:
ctx.slots.inject('settings.section'); - 染色:
MutationObserver+ 每 2s 轮询驱动的syncRowMarks(),扫描[data-row-key^="session:"],按「未读集(host)+ 官方置顶集(ctx.get('workspaces').list)」合成渐变,画在该行标题元素的行内样式上; - 文案:注册到官方 locale 命名空间
session-colorful-unread-pin-jobs(随界面语言切换,locale 服务缺失时中文兜底)。
- 菜单条目:
- 一次性残留清理——1.x 在新架构下会把转换结果写回盘上官方
client.js;2.0.0 启动时若发现盘上仍带 v1 注入标记,就用storages里的bundle-*.client.js.orig还原原始字节并对齐clientModulesgraph。对干净环境是 no-op。
从 1.x 升级到 2.0.0
破坏性变更(因此版本号为 2.0.0):
- 移除插件自研的置顶功能(菜单条目、
topIds持久化、/top端点、置顶排序分区)——请改用官方「置顶会话」(官方已支持置顶持久化与置顶分区排序)。 - 移除「模型更新」排序模式与
/timestamps端点、Deep diving「距 agent 上次输出」第二列。 - 移除「存活后台 shell 任务=紫色」指示(新版会话列表快照已无 jobs 镜像,且该能力与官方后台任务 UI 重叠)。
- 不再改写官方 bundle,因此不再需要锚点自检(
check-anchors/check-migration已删除,改为check-env/check-host)。
升级步骤:
- 升级插件后重启 DSH(host 半随进程加载;client 半由
client-hmr的 500ms 轮询自动热更,刷新页面即生效)。 - 未读集合与「发送即清」设置自动沿用;
unread.json里的topIds会被忽略(不再读写),置顶请用官方菜单重新置顶。 - 盘上残留由 host 半自动还原;
storages里的bundle-*.client.js.orig保留作 v1 回退,可手动删除。
限制
- 需要 DSH ≥ 0.1.7-alpha.2:旧版没有官方插槽与
data-row-key,UI 平面不会生效(host 数据平面仍工作)。用npm run check-env可离线核对当前安装树是否满足契约。 - 染色依赖会话行 DOM 的两个稳定锚:
data-row-key="session:<id>"与标题 class 后缀_title。官方改这两者后需重新适配;相比旧版的 bundle 锚点替换,这里失效时只是不染色,页面与菜单不受影响。 - 折叠的工作区分组里的会话行不渲染,因此展开分组时才会着色(观察器会在行出现时立即补画)。
- 「当前打开的会话」以列表 store 中
retainedBy.mainView的持有者为准;多标签页各自独立判定与清除。 - 主题自适应依赖主题系统把主题写到 body 主题属性、并以 alias 变量提供品牌色;第三方主题若不经过该机制改色,染色不会跟随。
- 自动未读的判定粒度是「模型白名单事件」:
llm/retry等不产生内容的异常事件不计。
开发
npm run build # 校验并产出 lib/index.js
npm run build:client # 校验并产出 lib/client.js
npm run check-host # host 半单测:存储/迁移、HTTP 平面、v1 残留清理
npm run check-env # 离线校验当前 DSH 安装树是否提供插件依赖的官方扩展点
npm run check # 两者都跑
dsh plugin --profile web add /path/to/dsh-session-colorful-unread-pin-jobs
许可
MIT
评论
评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。