dsh-session-console · 会话总控
DeepSeek Harness 的「左侧对话管理员」。侧栏多一个图标,点开是一张覆盖全部会话的仪表盘: 状态、消耗、热度、健康度一屏看完;再用一句自然语言指到某个对话,把话派进去,把返回读回来。
三个能力
1. 仪表盘(读全局)
| 指标 | 含义 |
|---|---|
| 会话总数 / 运行中 / 冷会话 / 空白 | 全局状态分布 |
| 累计 token(输入 / 输出 / 缓存读 / 缓存写) | 来自 tokenUsage projection,不扫归档 |
| 缓存命中率 | cacheRead ÷ (input + cacheRead + cacheWrite) |
| 今日活跃 / 本周活跃 | 按会话最后活跃时间分桶 |
| 上下文压力 | 来自 contextPressure projection,显示 pressureTokens ÷ contextWindow 的百分比 |
| 模型 | 来自 modelSelection projection 的 next(已合并 pending),显示 provider/model |
| 热度 | 单一分值:100/(1+静默小时/6) + log10(1+token)*8 + log10(1+事件)*5 + 运行中40 |
| 最热 / 按工作区聚合 | 谁在烧 token、哪个目录最忙 |
列表支持 全部 / 运行中 / 今日 / 冷会话 / 空会话 过滤,热度 / 消耗 / 最近 排序,以及标题与路径的即时过滤。
2. 指代(读一句人话)
在「指代与派任务」里输入 示例项目的相关内容怎么样了:
- 剥掉「怎么样了 / 情况 / 进度 / 相关 / 内容 / 帮我 / 看看」这类口头语,留下主语
示例项目; - 拿主语去比对每个会话的标题、
cwd、目录末段、agent preset、会话 id(权重 6 / 4 / 3 / 1 / 1); - 子串命中给满权重加成,其余用 CJK bigram + 拉丁词的 Dice 相似度;
score ≥ 40且不存在跨工作区的同分对手才算"锁定",否则把候选列出来让你点。
比对用的是会话 header 里的真实 cwd(不是归档目录那串 ~6570~636E~… 编码名),所以工作区目录叫 示例项目-v2 时,一句「示例项目的相关内容」就能直接对上。
同一个工作区里往往有好几个同主题的历史会话(命中分数相同)。这类"兄弟会话"不算歧义,直接取其中热度最高的一个;只有跨工作区出现同分对手时才判定为歧义,把候选列出来让你点。
3. 派任务 / 看返回(写进别的对话)
选定目标后写一句话,两种投递方式:
- 排队(
queue):作为下一轮输入排进去,目标对话空闲时立刻跑; - 打断插入(
steer):如果它正在跑,就把这句插进当前这一轮。
走的是 UI 输入框同一条通道(sessionController.prompt),所以冷会话会自动恢复,消息也会持久化。派完可以直接在详情卡里读最近的用户/助手消息、轮次/工具调用/工具失败/异常轮次统计、最后一次失败原因;也可以一键跳到那个对话看完整上下文。
安装
已发布到 npm:
plugin_manager install_bundle target=dsh-session-console
也可以直接从 GitHub 装:
plugin_manager install_bundle target=github:onlyinliu/dsh-session-console
开发时从本地目录装(改动即时生效):
plugin_manager install_bundle target=D:\create\dsh-session-console
装完重开一次 DSH,侧栏才会出现图标。
发布状态
| 渠道 | 状态 |
|---|---|
| 源码仓库 | ✅ https://github.com/onlyinliu/dsh-session-console(10 个文件在 main,topics 含 dsh-plugin) |
| npm | ✅ dsh-session-console@0.1.0,2026-11-04 发布 — https://www.npmjs.com/package/dsh-session-console |
| 插件市场条目 | 🕒 PR https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/11917(已提交,等 CI 的"仓库满 1 天"这一条自动放行) |
市场 CI 的「仓库年龄」不是错误
awesome-dsh-plugin 的 scripts/check-submission.mjs 里有 MIN_AGE_DAYS = 1:仓库创建不满 1 天直接判失败。
报错文案明说这是唯一失败项、检查会自己重跑放行,不需要重新提交、push 或关了重开。
本仓库 created_at = 2026-11-04T07:19Z,所以 2026-11-05T07:19Z 之后的 CI 就会绿。
以后发新版本
- 改
package.json的version; - 发布必须用勾了 Bypass 2FA 的 Granular Access Token(这类 token 直接 publish 仍可用到 2027-01,之后要迁 trusted publishing):
printf 'registry=https://registry.npmjs.org/\n//registry.npmjs.org/:_authToken=npm_xxx\n' > /tmp/rc
npm publish --userconfig /tmp/rc --registry=https://registry.npmjs.org --access public
本机
~/.npmrc的默认 registry 是registry.npmmirror.com(只读镜像,不能 publish), 所以必须显式带--registry=https://registry.npmjs.org。 发布返回202后,版本元数据先出现、tarball 在 CDN 上还有几秒到几十秒延迟,属正常。
- 把源码同步到 GitHub。本机到
github.com:443的 git 连接不稳定(Recv failure: Connection was reset), 可以改用 REST Contents API 逐文件PUT /repos/<owner>/dsh-session-console/contents/<path>推送。
市场条目规则(已按此写好并提 PR)
- 文件位置
data/plugins/<owner>__<repo>.yml,一个插件一个文件;README 是生成的,别手改。 description.en必填、以句号结尾;含:(冒号+空格)要整段加引号。- CI 依次查:条目数(一个 PR 最多 3 条)→
package.json必须声明dsh.bundle(只声明dsh.client会被拒)→ 仓库满 1 天 → lint 与站点构建。 - 条目里不要手写
npm:键,映射由站点自动采集;npm 包的repository必须指回列表里的仓库。 - 合并后站点与 dsh-market 通常一天内收录。
本机前置条件
| 项 | 现状 |
|---|---|
git |
2.56.0 ✅ |
npm / node |
10.8.2 / v20.19.6 ✅ |
gh CLI |
❌ 未安装 —— 建仓走了 GitHub Device Flow + REST API,不需要它 |
| 发布凭据 | 不在仓库里:GitHub 用 device flow 换的 OAuth token,npm 用勾了 Bypass 2FA 的 Granular Token |
结构
dsh-session-console/
├── package.json # dsh.bundle.patch + dsh.client 双端声明
├── cordis.patch.yml # insert: id session-console → name dsh-session-console
├── icon.svg
├── locale/{zh,en}.json # meta.title / meta.description(插件市场必读)
└── lib/
├── index.js # Host:HTTP 聚合路由 + 5 个 agent tool
└── client.js # Client:sidebar.panellist 图标 + main 面板
Host 路由(同源,仅回环地址可访问)
| 方法 | 路径 | 作用 |
|---|---|---|
| GET | /plugins/dsh-session-console/overview |
全量会话行 + 汇总(8s TTL 缓存,并发去重) |
| GET | /plugins/dsh-session-console/match?q= |
一句话 → 候选会话 + 是否锁定 |
| GET | /plugins/dsh-session-console/tail?id=&limit= |
某会话的最近消息与健康度 |
| POST | /plugins/dsh-session-console/dispatch |
{text, sessionId | query, mode} → 派任务 |
| POST | /plugins/dsh-session-console/cancel |
{sessionId} → 停止当前轮 |
Agent 工具(装好即可被任意对话调用)
session_console_overview、session_console_find、session_console_tail、session_console_dispatch、session_console_cancel。
也就是说:在任何对话里说「帮我看看哪些会话最费 token」或「让示例项目那个会话把用例补完」,模型可以直接调它。
实现要点
- 不注册新的 session projection:纯 JS 插件拿不到 zod schema 的声明合并,所以只读已有 wire 投影(
title/tokenUsage/contextPressure/sessionListMetadata/modelSelection),聚合放在 Host HTTP 层,8 秒 TTL + inflight 去重。 - 不往会话日志里写新事件类型:Session 会拒绝重开;派任务复用
sessionController.prompt。 - 不用 iframe、不 require
@deepseek-ai/dsh-client-*:Client 半边只有一个平台 seed(react),所有控件手写,配色全部走--dsw-alias-*主题 token,light / dark 自动跟随。 - 仅回环:每个路由都校验
Host/Origin与监听地址匹配,Cache-Control: no-store。 - 全部注册包在
ctx.effect(...)里并返回清理函数,面板在活动状态下被卸载时会自动layout.selectPanel(null)。
已知边界
- 热度公式是启发式的,想改就改
lib/index.js的heatOf。 - 指点只做字面 + 模糊匹配,不做语义 embedding;说「那个改权限的」这类纯意译会落到候选列表让你确认,而不是硬猜。
- 冷会话的第一条派发会触发 resume,可能有一两秒延迟。
- 有些历史会话来自别的机器(
cwd指向/home/deep/...这类本机不存在的路径),它们能读、能显示,但派进去会立刻turn/end: blocked。这类会话在列表里用「空会话 / 冷会话」过滤器可以分开看。
No comments yet. Be the first to write one.