dsh-session-bundle:一条命令把会话连同产出文件打成 ZIP

前言

在 DSH 里做一个有产出的任务,比如改完一批文件、生成几张图,结束时往往要交代”这次干了什么、留下了什么”。核心自带的 /export 只能拿到原始 session.vN.jsonl 和日志里引用的附件,丢掉了可读的对话,也不复制工作目录里被写入、修改、通过 present 提交的文件。社区里常见的可读转录插件则反过来,只管对话,不管产出文件。

zhyunran/dsh-session-bundle 补的就是这一格:一条 /bundle 命令,把可读对话、原始日志、附件和本会话产出/改动的文件写进一个 ZIP,落到宿主机磁盘。

这是什么

维护者 zhyunran 的 DSH 客户端插件,分类归在客户端。当前 GitHub 1 星,另有 22 个单元测试在仓库里跑通(node --test test/*.test.mjs)。README 明确标注:无需构建步骤,无运行时依赖,要求 DSH 0.2.x。

它解决的是”导出不完整”:/export 拿不到 conversation.md,也拿不到工作目录里 session 自己写出来的东西;而后者恰恰是判断一次 Agent 运行结果的依据。

导出包里有什么

ZIP 落盘后的目录结构,来自 README 的 “What’s inside”:

README.txt
conversation.md        readable transcript
session.v4.jsonl       raw durable event log (JSON Lines)
manifest.json          machine-readable file index, counts, skips
files/
  attachments/         bytes of every file/image attachment
  produced/            files from present/write/edit/str_replace_editor
  external/            changed files outside the working directory
workspace/             copies of files changed in working directory

conversation.md 的结构是:头部写出 session id、工作目录、创建/导出时间、模型、turns、消息与工具调用计数;每个 turn 用 ## Turn N 分开;用户消息带来源标注(user、agent message from <session>、schedule 等);工具调用与结果放在可折叠块里, arguments 完整,输出做截断;附件指向 files/attachments/;present 过的文件和每个 turn 的改动文件带指向 bundle 内部的链接;最后有一张完整文件清单表。

系统提示、developer 消息、请求头、reasoning 和注入的运行时上下文默认从 conversation.md 中省略(两项都可配置打开)。session.v4.jsonl 才是原始事实来源。

如何判断”本会话产出”的文件

采集器按下面顺序取并集,按绝对路径去重,来自 README “How files produced by this session are found”:

  1. 附件:user、assistant 和 tool-result 内容里所有 file/image 块,字节来自附件存储。
  2. present 过的文件:deliverables/presented 事件,present 工具调用作为兜底。
  3. 文件工具写入:write、edit、str_replace_editor 调用,相对会话工作目录解析。
  4. 工作区变更摘要:workspace/changes 事件加 ctx.workspaceChanges.summary(),即宿主机 git-worktree/文件工具按 turn 记录的变更快照。这一步能覆盖 shell 命令产出的文件。注意这些摘要只存在于宿主内存,重启后可能丢失。
  5. 修改文件扫描:includeWorkspace: auto 且没有摘要时触发(always 则始终触发),扫描工作目录下 mtime 晚于会话开始时间的文件,跳过 .git、node_modules、缓存和虚拟环境等。

被删除的文件只记在 manifest.json 的 skipped 列表里(missing (deleted or moved)),内容无法从磁盘恢复,只有变更摘要里的名称和计数。所有内容都有大小上限并计算 SHA-256 写进 manifest。

安装与启用

安装命令来自 README 原文,npm 方式标注为”if published”,不要凭插件名拼接 dsh plugin add github:owner/repo。

# local tarball (absolute path)
dsh plugin --profile <profile> add C:\path\to\dsh-session-bundle-0.1.2.tgz

# or GitHub tarball (git not required)
dsh plugin --profile <profile> add https://codeload.github.com/<owner>/dsh-session-bundle/tar.gz/<40-char-commit>

# or npm, if published
dsh plugin --profile <profile> add dsh-session-bundle

装完重启一次 DSH,然后输入 /,bundle 应该出现在命令列表里。仓库 package.json 里版本号是 0.1.2,license 是 MIT,对 @deepseek-ai/dsh-tools 的 peer 依赖区间是 >=0.2.0-rc.1 <0.3.0,engines.node 要求 >=22.19.0。

两种用法

由人触发:在要导出的会话里直接输入 /bundle,无参数。

/bundle

不带参数时 ZIP 写到 Windows 下的 Desktop/DSH-Exports/,其他平台写到 <home>/DSH-Exports/,命令结果会回显确切路径,不弹浏览器、不弹文件选择框。

由 Agent 触发:让 Agent 调用 export_session_bundle 工具,例如说”把这个对话和它产出的文件导出成一个包”。

{
  "include_workspace": true,   // optional: force a modified-file scan
  "include_raw_log": true,     // optional
  "output_dir": "D:/exports"   // optional
}

三个字段都是可选的,输出目录和包含范围也可通过 profile 层配置固定下来。

配置

配置写在 <DSH_HOME>/profiles/<profile>/cordis.patch.yml,README 给出的示例:

- id: dsh-session-bundle
  config:
    outputDir: 'D:/exports'     # default: Desktop/DSH-Exports or <home>/DSH-Exports
    includeWorkspace: auto      # auto | always | never
    includeAttachments: true
    includeRawLog: true
    includeReasoning: false
    includeInjectedContext: false
    maxFileBytes: 52428800          # 50 MiB per file
    maxTotalBytes: 314572800        # 300 MiB per bundle
    maxWorkspaceFiles: 300
    maxWorkspaceBytes: 209715200    # 200 MiB for workspace copies
    maxToolChars: 4000              # per tool call/result in conversation.md
    maxMessageChars: 20000          # per message in conversation.md
    maxRawLogBytes: 52428800
    ignoreNames: ['.git', 'node_modules', '__pycache__', '.venv', 'venv', '.next', '.cache']

字段含义按 README 的表格:includeWorkspace 为 auto 时有摘要用摘要、没有就扫描,always 两者都做,never 不做工作区快照(显式产出文件仍保留);includeReasoning 和 includeInjectedContext 控制 conversation.md 里是否带 reasoning 块和注入的用户角色上下文。配置非法时会回退默认值并记一条日志,不会阻止 DSH 启动。

适用场景与注意事项

适合需要在任务结束后做归档、交接或复现的人:一份 ZIP 同时有可读对话、机器可读索引和产物本身,比手工复制工作目录信息完整。也适合拿它对比会话实际改动是否与 workspace/changes 摘要一致的场景,README 称已在 DSH 0.2.0-rc.2 上做过端到端验证。

需要注意几点。第一,插件以当前 DSH 进程的权限运行,能读到工作目录里的文件;安装前建议先审一遍源码和 MIT 许可证,从 skillhub 目录页或 GitHub 仓库获取。第二,导出依赖宿主内存里的变更摘要,进程重启后摘要丢失,includeWorkspace 会退化为 mtime 扫描,期间磁盘上的变化不区分来源。第三,有大小预算:单文件 50 MiB、附件加产出共 300 MiB、工作区副本 300 个文件 / 200 MiB、原始日志 50 MiB,超限的部分只会记进 manifest.json。第四,当前星标只有 1,属于刚起步的项目,README 中”端到端验证”的表述也限于作者自己的环境。

小结

dsh-session-bundle 做的事其实很小:把会话对话、原始日志、附件和本会话产出文件合并成一个 ZIP,落到宿主机磁盘。相比核心 /export 它多了可读转录和工作目录产物,相比只做转录的插件它多了产出文件,方向上正好补上中间那块缺口。目录页在 https://www.skillhub.cn/plugins/zhyunran/dsh-session-bundle ,源码在 https://github.com/zhyunran/dsh-session-bundle 。

羽毛球分组比赛记分
小程序二维码

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

小夜