DeepSeek Harness 会话引导栏(Session Rail)

前言

DeepSeek Harness(DSH)在本地运行多个会话时,很难一眼看出哪些在跑、哪些在等、哪些已经结束或出错。手动展开工作区、点进每个会话去查看,效率很低。

Session Rail 插件在 DSH 右侧栏增加一个常驻的“进度”视图,并在对话页面顶部标题栏展示五个状态计数(运行、询问、出错、中断、未读),在左侧工作区行展示徽标。这些信息都来自宿主提供的事件流与只读接口,无需额外数据上报。

插件定位

  • 名称:dsh-session-rail
  • 维护者:zengxiaolou
  • 依赖:DSH >= 0.2.0-rc.1 < 0.3.0-0
  • 许可证:MIT
  • 安装方式:本地目录链接安装(非 npm registry)

核心功能

1. 顶部五段计数

对话页面顶部标题栏右侧、右侧图标按钮左侧的空白处,常驻五个状态计数:

  • ● N 运行(蓝色):有活跃回合且正在执行工具调用的根会话数。
  • ● N 询问(橙色):当前回合停在 ask_user_question,等待用户输入。
  • ● N 出错(红色):上一回合以 blocked 或 error 结束且未查看。
  • ● N 中断(灰色):上一回合以 aborted 或 interrupted 结束。
  • ● N 未读(绿色):已正常结束(completed 或 max-tokens),但浏览器尚未查看。

计数来源:

  • 运行数:客户端 sessions.list 的 running 字段,结合 /turns 排除“在等待回答”的会话。
  • 询问数:当前回合内存在未产生 tool/result 的 ask_user_question 调用。
  • 出错/中断/未读:从 /turns 读取最后一个回合的 turn/end.data.reason.kind,对比已读水位(客户端维护)。

颜色与行为:

  • 颜色来自会话结局:completed/max-tokens → 绿,aborted/interrupted → 灰,blocked/error → 红,查不到 → 绿(未读)。
  • 数字为 0 的整段隐藏;五段都为 0 时显示一颗淡点(透明度 0.45,hover 变为 0.95)。
  • “在跑”与“等你回答”分开算:只有当前回合内有未完成的提问调用才计入询问,历史回合不计。
  • 轮询频率:运行数订阅 sessions.list,状态真变才更新;结局每 15s 向宿主批量问一次(最多 24 个),页面不可见时不发。

忽略机制:

  • 默认规则:以 dsh-automation-session- 前缀的定时任务会话,已正常结束的不计入未读,仅 error/中断进红/灰段。
  • 显式忽略:浮层每行右侧有“忽略”按钮,写入 localStorage 的 dsh-session-rail:ignore:v1({ v: 1, sessions: [...] }),被忽略的会话不再计入任何计数,但仍在侧栏可打开。

交互:

  • hover / 键盘 focus 仅预览,移开即收起。
  • 点击 chip 钉住浮层,浮层内行为才是跳转入口;再次点击或点击外部/按 Esc 关闭。

2. 左栏工作区徽标

左侧工作区列表的每一行尾,根据会话状态显示一个徽标 ● N:

  • 只有当 running + question > 0 时才显示徽标。
  • 有提问会话时徽标为橙色,否则为蓝色。
  • 徽标由插件在 sidebar.footer.action 处的空组件每 1.5s 重画,通过原生 DOM 挂载到 [data-row-key^="workspace:"] 元素上。

开关:

  • localStorage["dsh-session-rail:workspace-badge:v1"] = "off" 可关闭徽标,removeItem 恢复。

已知边界:

  • 注册表返回的 sessionIds 未按归档集过滤,归档会话若仍在跑会被计入。
  • 自动化会话(如 dsh-automation-session- 前缀)目前计入,若发现长期亮灯,可按 origin 或会话名前缀进一步过滤。

3. 右侧栏进度 tab

在 DSH 右侧栏新增“进度”标签,与 PR 标签并排。该 tab 显示:

  • 本会话运行状态:运行中/空闲、当前轮次、已用时长、工具调用数、最近一个工具、上下文占用(已用/窗口,按 65%/85% 变色)。
  • 长任务列表:状态、百分比、最新消息、相对时间。

数据来源:

  • 本会话状态:turn/start、turn/end、tool/call 事件。
  • 长任务:<cwd>/.dsh-progress/<session-id>/*.jsonl(遵循 dsh-task-progress 协议)。

第一张卡不依赖任何 producer:只要会话在跑,就会显示“第 N 轮 · 1 分 45 秒 · 15 次工具调用 · bash”。

4. 宿主只读接口

插件提供 /api/session-rail 前缀的只读接口:

  • GET /api/session-rail/turn?sessionId=<会话 id>:返回该会话尾部最多 400 条事件流,包含运行状态与上下文占用。
  • GET /api/session-rail/turns?ids=<逗号分隔,最多 24 个>:批量获取每个会话最后一个回合的结局。
  • GET /api/session-rail/workspaces:返回工作区到 sessionIds 的映射(用于左栏徽标)。
  • GET /api/session-rail/progress?cwd=<绝对路径>&sessionId=<会话 id>:获取特定会话的长任务进度。
  • GET /api/session-rail/changes?cwd=<绝对路径>:保留为诊断接口,0.1.5 起无客户端使用。
  • GET /api/session-rail/sources?cwd=<绝对路径>:同上。
  • GET /api/session-rail/report?boot=&stage=&service=&tabs=:客户端启动信标(用于诊断)。
  • GET /api/session-rail/state:版本号与信标记录,用于检查客户端是否加载。

接口限制:

  • 同源校验:带 Origin/Referer 且 host 与请求 Host 不一致返回 403;缺 Host 返回 403;非 GET 返回 405;未知路径返回 404。
  • 除 /report 写一条内存记录外,全部只读:不写工作区、不写会话日志、不改仓库。
  • /turn 不落盘,只读尾部事件流。
  • 上下文占用 = inputTokens + cacheReadTokens + cacheWriteTokens,建议不要只看 inputTokens。

/turn 响应示例:

{
  "ok": true,
  "live": true,
  "running": true,
  "turn": 5,
  "startedAt": 1792632091266,
  "elapsedMs": 122300,
  "toolCalls": 19,
  "lastTool": "bash",
  "lastEventType": "job/registered",
  "lastEventAt": 1792632191436,
  "seq": 949,
  "usage": {
    "inputTokens": 227,
    "outputTokens": 188,
    "cacheReadTokens": 318464,
    "contextTokens": 318691
  },
  "contextWindow": 1048576,
  "fillPercent": 30
}

安装与启用

  1. 下载或克隆仓库到本地目录,例如 /path/to/session-rail。
  2. 执行本地链接安装:
dsh plugin --profile desktop add /path/to/session-rail
  1. 硬刷新浏览器(Cmd/Ctrl+Shift+R)。
  2. 宿主侧改动需重载插件行(关闭再打开)或重启 DSH。

测试

插件提供自测脚本:

npm test

测试覆盖:

  • test/host.test.mjs:13 组断言,覆盖 /turn 运行/闭合/未知会话、/changes、/sources、信标与 /state、传输守卫。
  • test/client.test.cjs:stub React 渲染进度 tab 与顶部计数,覆盖描述符、badge、运行状态卡、空态、已读水位跃迁、跳转清理与“空闲只剩一颗点”的渲染。

测试不碰真实工作区、不联网。

诊断

若页面未加载插件,可通过以下命令检查:

curl -s localhost:60606/api/session-rail/state | python3 -m json.tool
  • clientReports 为空:页面未加载插件客户端模块(旧页面未刷新或 dsh.client 未扫描)。
  • 有 stage=apply 且 service: false:加载了但未等到 betterSidebar 服务。
  • 有 stage=registered 且 tabs 包含 session-rail:progress:标签已注册,应能在标签条中看到。

/state 同时返回 clientGraph:ours: true + clientReports: [] 表示打包正确,仅页面未重载。

适用场景与注意

  • 适合需要同时管理多个会话、希望快速识别运行状态、等待输入和已结束会话的场景。
  • 插件以 DSH 进程权限运行,安装前建议检查源码与许可证。
  • 左栏徽标定位依赖宿主组件结构,部分行为需重启后手验,拖拽/展开后需确认无重影。

结语

Session Rail 通过顶部计数、左栏徽标与右侧进度 tab,将多会话状态集中在视野中,减少逐个展开和翻找的时间。它不改变宿主行为,仅通过只读接口与原生 DOM 注入增强视图,适合作为 DSH 日常开发的辅助工具。

  • 目录页:https://www.skillhub.cn/plugins/zengxiaolou/dsh-session-rail
  • GitHub:https://github.com/zengxiaolou/dsh-session-rail
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye