DSH Plugins Marketplace

DSH Plugins

Plugins

/

Sessions & Messages

/

dsh-session-lazy-view

d

dsh-session-lazy-view

Manifest valid

Read-only lazy session viewer: lists sessions with stat only, then decompresses just the tail Zstandard frames to inspect recent events; includes search, stats, and export in a standalone /lazyview pa

hasBundlePatch

@240xu/dsh-session-lazy-view

怎么打开:安装后访问 http://<dsh-web-地址>/lazyview 即是独立面板页; DSH 宿主侧边栏没有本插件入口是有意设计(纯只读工具,不污染主界面)。 可选:若你另装了 dsh-devkit,Ctrl+K 命令面板里会有「打开」入口;没装也不影响本插件。

DSH web 插件:会话惰性查看器(纯只读)。列出 ~/.dsh/sessions 下全部会话(只 stat 不解压), 并可只解压任意会话文件的最后 1–2 个 zstd 帧快速查看最近发生的事件,不碰整份文件。

不做删除、不做归档、不是 Trajectory 替代品;对 ~/.dsh/sessions 零写入。

10 秒速查

dsh plugin --profile web add @240xu/dsh-session-lazy-view
# 重启后直接访问 http://<dsh-web-地址>/lazyview
  • 纯只读:不删除、不归档、不写 ~/.dsh/sessions
  • 不想逐个装:dsh plugin --profile web add @240xu/dsh-plugin-hub
  • 卸载:dsh plugin --profile web remove @240xu/dsh-session-lazy-view

原理

session.v3.jsonl.zstd 是连续多帧的独立 zstd 帧(魔数 0x28 B5 2F FD): 帧 0 恰好一行 session header JSON;之后每帧一批 newline-delimited JSON 事件, 最后一帧结束于 EOF。因此从文件尾部读一个窗口、扫帧魔数、只解压候选帧, 即可拿到最近事件,成本与文件总大小无关(旧格式 session.jsonl.zstd 为单帧,等效于解压整份,但同样走这条路径)。

安装

零 npm 依赖(只用 node:fs / node:zlib / node:path / node:url; @deepseek-ai/schemastery 由 DSH profile 树自带,无需安装)。

# 方式 A(推荐):DSH 官方插件命令(内部走 pnpm,正确登记 lockfile 与 bundles)
dsh plugin --profile web add @240xu/dsh-session-lazy-view

# 方式 B:npm pack 直解(profile 是 pnpm workspace,不要在 profile 内直接 npm i ——
# workspace 根的 link:/ 依赖会让 npm 报 EUNSUPPORTEDPROTOCOL)
cd ~/.dsh/profiles/web/node_modules
npm pack @240xu/dsh-session-lazy-view
mkdir -p @240xu/dsh-session-lazy-view
tar -xzf 240xu-dsh-session-lazy-view-*.tgz -C @240xu/dsh-session-lazy-view --strip-components=1
# 然后把 "@240xu/dsh-session-lazy-view" 加进 profile package.json 的
# dsh.profile.bundles 列表(lockfile/package-map 不一致时 pnpm install 会补齐)

# 方式 C:从源码拷贝(开发)
git clone https://github.com/240xu/dsh-session-lazy-view && cp -r dsh-session-lazy-view ~/.dsh/profiles/web/node_modules/

然后在 DSH web profile 的 cordis.patch.yml 里挂载(写法与 dsh-archived-sessions 完全一致)。若该文件已存在其它 - insert: 条目, 把下面 - id: 两行并入现有列表即可:

- insert:
    - id: dsh-session-lazy-view
      name: '@240xu/dsh-session-lazy-view'

重启 DSH web 实例后生效。

端点

前缀 /lazyview(受与 archived-sessions 相同的 loopback / same-origin 信任门保护):

端点说明
GET /lazyviewHTML 面板:按项目分组列出会话,>10MB 标红,每行 tail 按钮展开最近 2 帧,支持“上一页”
GET /lazyview/api/listJSON:{root, projects:[{project, sessions:[{sessionId, path, artifact, format, bytes, mtime, big}]}]},纯 stat
GET /lazyview/api/tail?path=<相对路径>&frames=2&skip=0JSON:从尾部解压 frames 帧;skip 为翻页偏移(跳过最新 skip 帧后再取 frames 帧)。帧内事件已文本化(role + 截断到 2000 字符的 text / tool-call / tool-result)

path 必须是 /api/list 返回的 path(相对 sessions 根,且必须以 session.v3.jsonl.zstd 或 session.jsonl.zstd 结尾);路径逃逸检查在服务端。

解析失败(坏帧、旧格式、窗口截断等)一律返回 {ok:false, error:{code, message}} 结构化错误,不会 500 崩面板。

已知限制

  • 旧格式 session.jsonl.zstd 单帧等于整份文件,tail 读取没有惰性收益。
  • 尾部窗口默认 1MB,最多增长到 64MB;极端情况下(单帧超过 64MB)返回 truncatedScan: true 且可能少帧,不会死循环。
  • 帧魔数理论上可能出现在压缩数据内部造成假候选;假候选解压失败后以 per-frame error 呈现,不影响其余帧。
  • 事件文本化只覆盖已验证的形状(user/assistant/system message、tool call/result), 其余事件类型输出紧凑 JSON 摘要。
  • 未做缓存:每次 tail 请求都重新读窗口,对调试场景足够。

离线验证

./verify.sh

用 node 直接 import ./lib/frames.js,对 ~/.dsh/sessions 下任一 .zstd 会话执行“读最后 2 帧”,打印事件条数与首条 role。

v0.2.0 新增

仍然是纯只读:全部新功能对 ~/.dsh/sessions 零写入(不缓存、不落盘), 依旧不删除、不归档、不碰任何侧边栏注册面——所有能力都挂在自己的 /lazyview/* HTTP 端点与 panel.html 面板里。

端点说明
GET /lazyview/api/search?path=&q=&max=20会话内全文搜索:流式逐帧解压做大小写不敏感子串匹配,命中返回 {frameIndex, seq, type, role, snippet}(命中点前后各 60 字符窗口)。达 max 截断;默认最多扫 500 帧,未扫完返回 partial:true。每帧之间 setImmediate 让出事件循环,客户端断开(AbortSignal)即中止扫描
GET /lazyview/api/stats?path=[&fast=1]会话统计:帧数、总事件数、按 type 分组计数、首/末事件时间、文件字节数、session header。fast=1 只流式扫描帧魔数(不解压、内存有界)给帧数/字节数
GET /lazyview/api/export?path=&frames=N把最近 N 帧(≤20)导出为 Markdown 文本下载(Content-Disposition: attachment)。文本在内存中生成直接响应,不写任何文件

面板集成:每个会话行新增「搜索」按钮(展开输入框 + 命中结果列表,命中 标注帧号/seq/type/片段,新搜索自动取消上一次);打开会话顶部新增「统计」 小节(先展示 fast 帧数/字节,按钮展开全量解压统计)与「导出 md」下载链接。

测试:npm test(即 node --test "test/*.test.js";零依赖,用 node:zlib 自造多帧 fixture, 覆盖搜索命中/截断/abort、stats 分组、export 渲染)。

性能取舍说明:

  • 解压是同步的(zstdDecompressSync),全量扫描在帧与帧之间用 setImmediate 让出事件循环(参照 dsh-src ZSTD_DECODE_YIELD_INTERVAL_MS 思路),单个大文件的搜索/统计不会长时间阻塞 web server;但一次请求 内整份文件会被读进内存(read-only,读完即释放),超大文件请优先 ?fast=1 或改用 tail。
  • 搜索只覆盖事件文本化后的可见文本(describeEvent,单条截断到 2000 字符);无法文本化的行仍按原文参与匹配。
  • 全量统计对大文件是秒级操作(每帧解压一次);面板默认只拉 fast 统计, 全量按需展开。

v0.2.1 评审修复

  • 可发现性(P0):README 与面板页顶部均加显著说明——面板是 /lazyview 独立页,宿主侧边栏无入口是有意设计(纯只读工具);面板页新增 「复制面板链接」按钮;README 注明装了 dsh-devkit 可用 Ctrl+K 打开。
  • S1(P1):360px 表格溢出修复——session id 列截断省略(title 悬停看全), mtime 列在 ≤480px 隐藏(hide-sm)。
  • S2(P2):全部按钮触控目标提升到 ≥44×44px。
  • S3(P2):统计小节预留固定高度占位(fast→full 替换前锁定高度),防 CLS。
  • S5(P3):#status 加 role="status" aria-live="polite",读屏可闻。

v0.3.0 Timeline 视图

按 turn 分组的正序事件时间线(vscode Timeline 式阅读投影),设计文档见 timeline-design.md:

  • 会话打开视图顶部新增「时间线」按钮,与帧流互斥切换;数据复用 /api/tail 翻页到文件头后按 seq 正序拼接(无需新端点)。
  • 分组规则:有 turn/start 事件时它开新组;历史格式以 user/message 为组边界。组默认折叠一行摘要,展开显示全部事件;折叠状态存内存。
  • Go to Message 深链:/lazyview?session=<id>&seq=<n> 自动打开会话、 进时间线、展开目标组并高亮首个 seq≥n 的事件。
  • message-ops 遮蔽标注:事件自带 surfaceOp(op:"replace")时,被替换 区间内的事件在时间线上渲染为半透明 +「已遮蔽」徽标;纯本地计算, 不依赖 message-ops 端点。只读铁律不变。
  • 纯函数(深链解析 / 遮蔽计算 / 分组)抽到 lib/timeline.js,一份两用: ESM 供测试,服务端剥 export 内联进面板。

v0.3.2 v4 会话支持

  • 用户实测发现:DSH 新会话写 session.v4.jsonl.zstd(帧 0 header version:4),面板此前只探测 v3/legacy,新会话全部不可见。
  • 修复:artifact 名单统一抽到 lib/artifact.js(session.vN.jsonl.zstd 形状正则),目录探测与 ?path= 校验共用;未来新版本号自动纳入, frames.js 无版本硬校验(header.version 原样透传),无需再改。
  • 面板 format 列区分 v4-multiframe / v3-multiframe / legacy-single-frame。

v0.3.3 可访问性补齐

  • 时间线分组折叠头(.ghead)从纯点击 div 改为键盘可达:role="button"
    • tabindex="0" + Enter/Space 触发 + aria-expanded 与折叠 Map 同步。

0.3.4 · Bug 猎场修复

  • [P1] 深链白屏:?session= 访问在 sessions.map 回调外引用回调参数 s → ReferenceError 被 catch 吞掉,面板一个会话都不渲染(0.3.0–0.3.3 全中)。改为在 project 的 sessions 内匹配 + 表格行定位打开按钮。
  • [P1] 遮蔽标注失效:applySurfaceOps 只认 fromSeq/toSeq(message-ops 从没写过 这种拼写)——真实数据是 start/end(新引擎)与 startSeq/endSeq(legacy)。三拼写 全兼容 + 真实拼写回归测试(原测试只喂假拼写 = 假绿)。
  • [P2] esc 补转义引号:title="…"/data-path="…" 是双引号属性而 listSessions 不校验目录名 → 本地目录名可属性逃逸存储型 XSS。

0.3.5 · frames.js 两个实测 bug(P2×2)

  • EOF 死循环:forEachFrame 读到 0 字节(stat 后并发截断)永不推进 → search/stats 请求悬挂 + fs 空转可拖垮 web 进程 → 0 字节即停。
  • countFrames carry 丢字节:每轮全零新缓冲从未拷入上轮 3 字节 carry → 跨 1MB 边界 zstd magic 全漏计(实测 magic@边界 count=0 应 1)→ ?fast=1 对 >1MB 文件 系统性偏低。回归测试在原代码上实证红(15/1 → 16/16)。

Comments

Loading…

Similar plugins

dsh-session-repair

by Equinox7379

Session log repair tool for DSH: scans zstd session logs for unknown event types and marks them ignorable with a compliant frame rewrite (backup included). Read-only scan by default.

Tools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Aug 15, 2026

dsh plugin --profile web add dsh-session-repair

by nateyu

A DeepSeek Harness settings plugin. It lists and deletes sessions the sidebar hides: archived sessions, or blank sessions whose log has no turn/start. A session whose log cannot be read is listed too,

Manifest valid

★ 0

MIT

JavaScript

Sep 11, 2026

dsh plugin --profile web add dsh-session-vault

by snow-The

Scans and repairs DSH session logs: re-encodes single-frame corrupt zstd files back to the multi-frame layout and marks unknown event types (e.g. llm/failover) as ignorable so older harnesses can load

Manifest valid

★ 0

MIT

TypeScript

Oct 19, 2026

dsh plugin --profile web add @snow-the/dsh-session-repair

by GroupWork888

Browse and read archived DeepSeek Harness sessions from a sidebar panel. A read-only viewer: it does not restore sessions to the sidebar.

UI & ExperienceTerminal & ClientsManifest valid

★ 0

MIT

TypeScript

Sep 29, 2026

dsh plugin --profile web add dsh-plugin-archived-sessions

by yfwu2020

DSH sidebar plugin: a floating recent-sessions sheet that blends into the sidebar

UI & ExperienceDevelopment & InfrastructureManifest valid

★ 0

MIT

TypeScript

Oct 5, 2026

dsh plugin --profile web add @yfwu2020/dsh-recent-sessions

by Yidien

DeepSeek Harness 会话「看清再动手」外挂:归档/彻底删除(系统回收站)+ 会话内容只读预览(Markdown),零依赖、不 patch 官方。

Manifest valid

★ 0

MIT

JavaScript

Sep 16, 2026

dsh plugin --profile web add dsh-session-sight