dsh-file-context:为 DSH 提供不可变的文件与 diff 上下文快照

前言

在 DSH 里让模型读本地源码时,常见做法是每次对话都重新读文件,或在提示里粘贴片段。文件一旦被编辑,更早轮次里模型「看过」的内容就和磁盘不一致,讨论行号、对比 HEAD 的 diff 时也容易混用新旧文本。

下面介绍的 dsh-file-context(维护者 LIghtJUNction,社区分类为「记忆」)做的是另一件事:在主机本地工作区内截取文件片段或 Git diff,生成带 id 与 revision 的不可变快照;之后源文件改了,仍可用 file_context_get 取回当初捕获的字节。它不替代远程沙箱,也不提供写文件或 Pi 文件浏览器,只负责「记住某一时刻的只读上下文」。

这是什么

  • 定位:DSH 0.2.1-rc.2 插件(npm 包名 @lightjunction/dsh-file-context,当前版本 0.1.0,MIT 许可证)。
  • 一句话:Immutable file and diff context snapshots for DSH。
  • 运行环境:Node >= 24;作者在本地用 Node 26 / TypeScript 5.9.3 开发与测试,Release CI 配置为 Node 24。

插件以当前 DSH 进程权限访问主机文件系统,路径校验有边界,但不是对抗恶意并发进程的安全沙箱;安装前宜自行查看 GitHub 仓库 源码与许可证。

核心功能

插件向 Agent 注册三个工具(无 Pi 菜单、预览或自动注入下一条 prompt):

  1. file_context_capture:捕获文件片段快照。参数示例 path、startLine、endLine;省略行范围时最多取文件前 500 行。返回不可变摘录、id、全文件 revision、范围与文本。若传入 expectedRevision 且文件已变,调用会被拒绝。
  2. file_context_get:用捕获时返回的 id 取回当时的摘录原文,即使源文件之后已修改。快照按规范化的工作区与 Agent 身份隔离;无 Agent 的 host 调用使用独立作用域。
  3. file_context_diff:捕获真实的 Git 工作树 diff 及解析后的 base commit。base 可为 HEAD 或完整 40/64 字符 commit hash;expectedRevision 用于校验结果 diff 的 SHA-256。

并发捕获会各自保留不可变快照;Agent dispose 会清掉其快照;重启 DSH 后内存中的快照全部丢失。内存中最多保留 64 个快照,无磁盘溢出或淘汰策略,触顶时调用会明确失败。

安装与启用

官方 README 说明:在 GitHub Release 发布后,将构建好的归档安装到 DSH profile。下列 URL 是 v0.1.0 资源预期位置,不代表该 Release 一定已发布;实际安装应使用同一 Release 附带的归档与 SHA256SUMS。

dsh plugin --profile headless add https://github.com/LIghtJUNction/dsh-file-context/releases/download/v0.1.0/lightjunction-dsh-file-context-0.1.0.tgz
dsh headless --dump-config

包内含 DSH bundle patch 与编译后的 JavaScript,不需要 Pi 依赖。安装后需重启 DSH。若你使用的不是 headless profile,把命令中的 profile 换成自己的即可。

默认 bundle 配置为 {}:各工具使用调用方 Agent 的工作目录。无 Agent 的 host 调用必须显式配置 root。若要把工作区固定到本机某目录,在 profile 的 cordis.patch.yml 中增加:

- id: dsh-file-context
  config:
    root: /absolute/local/project

root 必须已存在,在 DSH 主机上用 Node 文件系统 API 解析。远程 DSH world 或 sandbox 不会重定向这些操作:仅应在主机本地项目上启用,这不是 remote-world 适配器。

典型用法

README 给出的自然语言示例:向 DSH 说明——「Capture lines 1–30 of src/index.ts, then compare the current diff against HEAD.」模型会通过工具拿到结果;文件内容仍应视为不可信数据,而非指令。

工具调用层面可对应为:

file_context_capture({ path: "src/index.ts", startLine: 1, endLine: 30 })
file_context_diff({ path: "src/index.ts", base: "HEAD" })

捕获成功后用返回的 id 调用 file_context_get({ id: "<returned id>" }) 可在文件变更后仍引用最初摘录。

限制与行为(选用时注意)

读文件:拒绝路径遍历、绝对路径、路径中的 .git 段、符号链接文件或祖先、非常规文件、无效 UTF-8、二进制内容,以及超过 256 KiB 的文件。配置的 canonical root 本身可以解析为 symlink。全文件 revision 对完整 UTF-8 原文(含 BOM)做哈希;摘录会将 CRLF 归一化。摘录上限为 500 行、50,000 UTF-8 字节。

Git diff:工作区目录必须等于 Git 仓库根,且目标文件须为受约束的常规文本。外部 diff driver 与 textconv 被禁用,pathspec 按字面匹配;子进程带取消、5 秒超时与有界输出缓冲。不支持已删除文件或未跟踪文件的 diff。Diff 快照对 diff 文本哈希,而非工作树文件。

其他:不提供任何写文件。Linux/macOS 文件语义为设计目标,Windows 未验证。维护者仓库中可用 npm run check 做类型检查、行为测试与构建(使用真实 Cordis、DSH ToolRuntime 等,无需 live 模型凭证)。

适用场景

  • 需要在多轮对话中固定某段源码或某次 HEAD diff 的引用,避免「文件已改但上下文还在聊旧内容」时的混乱。
  • 希望用 expectedRevision 在捕获前确认文件或 diff 未变。
  • 工作区在本机可信目录,且 DSH 与 Git 根目录布局符合插件要求。

不适合:需要远程 world 内读文件、浏览 blame/历史、自动把快照注入下一轮 prompt,或依赖未跟踪/已删除文件 diff 的流程。

结尾

dsh-file-context 把「某一时刻的文件摘录与 Git diff」做成带 revision 的可检索快照,属于 DSH 生态里偏「记忆」的一类能力——插件化接入,不绑 Pi UI。社区目录页:https://www.skillhub.cn/plugins/LIghtJUNction/dsh-file-context(独立社区站点,与 DeepSeek / 幻方无官方从属关系)。源码与安装说明:https://github.com/LIghtJUNction/dsh-file-context。

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

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

小夜