description: "用 git 工作树快照和文件工具编辑前后的整文件捕获汇总每个顶层轮次改动的文件,以 workspace/changes Session 事件宣告,并在 Session 存活期间提供摘要和逐文件对比;配置、仓库要求与覆盖规则。"
English | 中文
本插件汇总每个顶层轮次改动了哪些文件、每个文件的行数,并提供每个所列文件在轮次开始与结束时的内容对比。比较轮次开始和结束时的 git 工作树快照;文件工具编辑的每个文件在首次编辑之前和轮次结束时各复制一份整文件,以此覆盖 git 覆盖不到的文件。没有仓库或没有 git 时,只列文件工具的编辑。Session 日志只收到一条写明轮号的 workspace/changes 事件;摘要和对比留在 Host 上,直到 Session 释放。Web 的改动文件卡片渲染它们。
正式提供的 Web bundle 挂载本插件。任何具备 subprocess 能力且 Host 上有 git 可执行文件的组合都可以挂载它:
- name: '@deepseek-ai/dsh-workspace-changes'
config:
maxFiles: 500
| 字段 | 默认值 | 含义 |
|---|---|---|
timeoutMs |
30000 |
单条 git 命令允许运行的毫秒数,超时则放弃本轮记录 |
outputMaxBytes |
8388608 |
每条命令保留的 git 输出字节数,diff 列表更大时放弃本轮记录 |
maxFiles |
500 |
单份摘要携带的最大文件数;total 仍报告完整数量 |
maxFileBytes |
2097152 |
文件在文件工具编辑前后被捕获、或从快照读出做对比所允许的最大字节数;更大的文件不提供对比,其中在文件工具编辑前后被捕获的也不带行数 |
diffTimeoutMs |
100 |
逐行对比允许运行的毫秒数,超时后退化为整文件替换 |
有工作目录且不是子代理来源的 Session 都会被记录;子代理 Session 不记录。快照通过私有 index 写入 Session 自己拥有的临时对象目录,仓库自己的对象库以只读 alternate 的方式挂接;仓库的 index、对象、工作树和 ref 保持不变,用户此前未提交的改动也不会进入摘要。Session 释放时删除该目录。工作目录内的嵌套仓库和 submodule 记录为 gitlink,其内部改动不会出现。不在任何 git 仓库内的工作目录不做快照。没有 git 时——或者 macOS 上只有 /usr/bin/git 的开发者工具桩程序时——同样定位不到仓库,插件记录一次日志。两种情况下摘要都只列下文所述的文件工具编辑,并以工作目录作为工作区;shell 的改动不会出现。
在 write、edit 或有修改作用的 str_replace_editor 调用运行之前,记录器把该路径上的文件复制到 Session 的临时目录,每轮每个路径只复制第一次,轮次结束时再复制一次;副本按其字节的 SHA-1 命名,相同内容只存一份。这一步不需要 git。快照覆盖到的路径保留 git 的行数;其余路径由副本提供,也就是匹配忽略模式的文件、仓库之外的文件,以及没有快照时的每一次文件工具编辑,行数来自两份副本的逐行对比,因此同一文件的重复编辑只计一次,文件工具编辑之后的 shell 改动也包含在内。轮次结束时内容没有变化的路径不会列出。超过 maxFileBytes 的副本不会保存:该文件列出时带 oversized,没有行数;两侧都这么大的路径同样列出,因为没读过的内容永远不能认定为没有改动。只差一个末尾换行的路径对比为两侧相同,而 git 仍会把那一行计入行数。/tmp 与平台临时目录下的文件被排除,除非它们位于仓库内。快照覆盖范围之外只通过 shell 命令做出的改动不会被记录。
每个文件携带持久的 path——位于工作目录内时为相对路径,否则为绝对路径——以及用于排序和标签的 display 路径:相对路径,仓库内位于工作目录之上的文件为 ../ 路径,家目录下的文件为 ~ 路径,其余为绝对路径。文件按 display 的码元顺序排序,因此上级路径和绝对路径排在工作目录自身文件之前。workspace/changes 事件只携带轮号;ctx.workspaceChanges.summary(sessionId, seq) 返回该序号的事件宣告的摘要,Session 已释放或本 Host 进程从未记录时返回 undefined。ctx.workspaceChanges.diff(sessionId, seq, index, signal) 对比该下标所列的文件:从两棵快照树或两份副本得出带三行上下文的 hunk;git 报告为二进制或某一侧含 NUL 字节时返回 binary;某一侧超过 maxFileBytes 时返回 oversized。逐行对比运行超过 diffTimeoutMs 时退化为一个替换全部行的 hunk,并标记 coarse。因此 Host 重启后重新打开的对话,先前轮次既没有卡片也没有对比。
无,因为记录器只追加一条仅写日志、只有客户端读取的 workspace/changes 事件,不注册任何面向模型的内容。
这里的内容不会进入模型请求,因此不影响提供方缓存复用。
core.splitIndex 会写 sharedindex.* 文件,git-lfs 会对改动文件运行 clean 过滤器并把对象存到 .git/lfs 下。rev-parse --absolute-git-dir;不支持的仓库格式或其他 git 失败会带着警告放弃本轮,而不是被当成普通目录。.gitignore 却带着大体积构建产物的仓库,在 Session 释放前会占用同等的临时空间。.gitignore。maxFileBytes,即使快照也覆盖该路径;副本随 Session 的临时目录一起删除。maxFileBytes。path 中保留原生分隔符;display 始终用斜杠分隔。