-
v0.3.12 — 文件与代码类工具全面优化(16 项) Stable
released this
2026-07-21 16:09:15 +08:00 | 3 commits to master since this release概述
本次版本聚焦 AI 文件与代码工程操作 的精细性和稳定性,对 13 个既有工具完成 14 项优化,并新增 2 个工具(
file_move/file_info),工具总数从 13 提升至 15。所有修改均通过tsc --noEmit类型检查和人工审查,无破坏性变更。
一、阶段一 · 紧急修复(F1-1 ~ F1-4)
针对既有 bug 和潜在数据安全问题进行紧急修复。
F1-1 · file_editor regex 计数 bug 修复
问题:
regex操作使用两次独立的RegExp实例(一次 match 计数、一次 replace 替换),由于g标志的lastIndex状态不同步,导致计数与实际替换次数不一致。修复:
- 强制 regex 含
g标志(若用户未传则自动追加) - 使用同一个
RegExp实例完成 match 计数 + replace 替换 - 逐行处理时每行匹配前重置
lastIndex = 0,避免g标志导致漏匹配
F1-2 · code_search 统一路径校验
问题:
code_search原先使用裸resolve()拼接路径,未经过isPathWithinWorkspace路径遍历防护和MEMORY.md受保护文件拦截。修复:统一改用
safeResolvePath,复用isPathWithinWorkspace(含realpathSync符号链接逃逸二次校验)+isProtectedWorkspaceFile两层安全检查。F1-3 · git_commit amend 模式增强
问题:amend 模式下
message字段为required,但 git amend 原生语义允许保留原 message — 这导致用户想修改提交内容但保留原 message 时必须重新输入。修复:
message字段改为非 required- 非 amend 模式仍强制要求 message(动态校验)
- amend 模式下:
- 提供 message → 用新 message 覆盖
- 未提供 message → 自动追加
--no-edit明确保留原 message(避免 git 打开编辑器 hang 等待输入)
- 返回值新增
amended: boolean字段
F1-4 · write_file append 模式原子化
问题:原
fs.appendFile内部为open(O_APPEND) + write + close,存在两个隐患:- 无
fsync:write 后数据仅停留在 page cache,系统崩溃可能丢失 - 大内容(> 4KB)非完全原子:可能被分成多个 write 调用
修复:改用显式
open('a') + 循环 write(直到 buffer 完整写入)+ fsync + close,在 保持 append 语义(O_APPEND 内核级追加) 的前提下保证数据持久化到磁盘,不改变并发行为。
二、阶段二 · 增强现有工具(F2-1 ~ F2-7)
提升文件读写和编辑工具的健壮性与适用性。
F2-1 · read_file 智能编码检测
问题:Windows 中文环境下大量历史文件为 GBK 编码,原
readFile(path, 'utf-8')会产生乱码;UTF-16 文件(带 BOM)也无法正确读取。方案:新增共享函数
decodeBufferWithDetection,采用 BOM 检测 + 三级降级策略:- BOM 检测(优先):
EF BB BF→ UTF-8 BOM,剥离 BOM 后解码FF FE→ UTF-16 LE,用utf16le解码FE FF→ UTF-16 BE,字节交换后用utf16le解码(含奇偶长度保护)
- 无 BOM 三级降级:
- UTF-8 strict(
fatal: true,失败则降级) - GBK(Windows 中文环境常见)
- UTF-8 loose(兜底,用替换字符代替非法字节)
- UTF-8 strict(
返回值新增
encoding字段,标识实际检测到的编码(utf-8/utf-8-bom/utf-16le/utf-16be/gbk/utf-8-loose)。F2-2 · read_file 支持 tail 模式
场景:读取大日志文件的末尾 N 行(类似
tail -n)。方案:新增
tail参数(1~2000),优先级高于offset/limit。返回值新增:start_line:实际起始行号(tail 模式下为max(1, total - tail + 1))mode:'tail'或'offset'
F2-3 · search_files 二进制过滤 + 智能编码检测
问题:搜索文件内容时会误读二进制文件(图片/可执行文件)产生乱码匹配,且非 UTF-8 文件无法被搜索到。
修复:
- 复用
isBinaryFile(NULL 字节检查,只读前 8KB)过滤二进制文件 - 改用
decodeBufferWithDetection读取文件内容,支持 GBK 等编码
F2-4 · search_files 多 glob 匹配
场景:一次搜索多种文件类型(如
*.ts,*.js,*.tsx)。方案:新增共享函数
matchAnyGlob(逗号分隔,任一匹配即通过)。list_directory和search_files的walkDir均改用此函数。空字符串视为匹配所有。F2-5 · file_editor 新增 find_replace 操作
场景:精准替换代码片段,但片段中含正则元字符(如
.*+?^$()[])会被误解析为正则。方案:新增
find_replace操作,采用字面量字符串替换(split + join统计匹配次数并替换),不解析任何正则元字符。参数:
find:要查找的字面量字符串(必填,非空)replace:替换字符串(默认空串)replace_all:true(默认)替换全部,false只替换第一个
F2-6 · file_editor regex 支持跨行匹配
场景:替换多行代码块(如函数定义、多行注释),原逐行匹配无法处理跨行模式。
方案:新增
multiline参数。为true时对整个目标内容块(start_line到end_line的 join)做正则替换,支持^/$匹配行首行尾、\s跨行空白等模式。F2-7 · file_editor 新增 backup 参数
场景:编辑重要文件前希望自动备份原始内容。
方案:新增
backup参数(默认false)。为true时在写入前将原始内容保存为${file_path}.bak。备份在写入前进行,确保即使写入失败也有原始备份。返回值新增backup_path字段(未备份时为null)。
三、阶段三 · 新增工具(F3-1 ~ F3-2)
补齐文件工程操作的关键能力缺口。
F3-1 · 新增 file_move 工具
场景:AI 需要移动或重命名文件/目录,原先只能通过
delete_file+write_file组合实现,数据安全性差。实现:
- 双路径
safeResolvePath校验(源和目标都必须在工作空间内 + 非MEMORY.md) - 禁止移动工作空间根目录
overwrite参数(默认false):为true时先删除已存在的目标再 rename- 自动创建目标父目录(递归
mkdir) - 使用
rename(同文件系统上为原子操作) - 权限策略:
WRITE+requireConfirmation: true+ 频率限制 30/min
F3-2 · 新增 file_info 工具
场景:AI 需要查询文件元信息(大小、时间、类型、编码、权限等),原先只能通过
run_command调用stat命令,效率低且需确认。实现:
- 路径
safeResolvePath校验 - 返回字段:
path/absolute_path/type(file/directory/symlink)/size/created/modified/accessed/mode(八进制权限位) - 文件类型额外信息(仅对普通文件):
is_binary:NULL 字节检查(读前 8KB)encoding:智能编码检测(仅非二进制文件,复用decodeBufferWithDetection)
- 只读前 8KB,避免大文件 OOM
- 权限策略:
READ,无需确认
四、阶段四 · 优化(F4-1 ~ F4-2)
F4-1 · diff_viewer 内存优化 + 统一路径与编码
优化 1 · Uint32Array → Uint16Array
LCS 算法的
lcs表从new Uint32Array((sm+1) * (sn+1))改为new Uint16Array(...)。LCS 长度最大值为min(sm, sn) ≤ 5000,远小于 Uint16Array 上限 65535,安全。内存占用减半。优化 2 · 统一路径校验 + 智能编码检测
原先 diff_viewer 手动调用
resolve + isPathWithinWorkspace + isProtectedWorkspaceFile三步,且文件读取用readFile(path, 'utf-8')。改为:- 用
safeResolvePath统一路径校验 - 用
decodeBufferWithDetection智能解码(支持 GBK/UTF-16 文件对比)
F4-2 · 错误处理统一
问题:各工具 catch 块中错误提取方式不统一(
(err as Error).message/String(err)/extractErrorMessage(err)),非 Error 抛出值(如字符串、对象)可能丢失信息。修复:扩展共享
extractErrorMessage(error, includeStderr?)支持 stderr 附加,并统一以下位置:diff-viewer.ts末尾 catch 块:(err as Error).message→extractErrorMessage(err)file-editor.tsregex 构造 catch 块:(err as Error).message→extractErrorMessage(err)code-search.tsexecute() 新增外层 try-catch(原先缺失,safeResolvePath异常会向上传播)
保留
searchWithRipgrep内部的err.stderr || err.message(stderr 优先语义,子进程错误信息在 stderr)。
五、阶段五 · 验证(F5)
F5-1 · TypeScript 类型检查
npx tsc --noEmit退出码 0,无类型错误。F5-2 · 人工审查
逐文件审查通过,覆盖维度:
- 路径校验:所有工具均使用
safeResolvePath,无裸resolve() - 错误处理:catch 块统一
extractErrorMessage,无非 Error 抛出值丢失 - 原子性:write_file / file_editor 用临时文件 + rename;file_move 用 rename
- 资源释放:所有 FileHandle 在
finally块中 close;临时文件在失败时清理 - 权限策略:file_move(WRITE+确认+30/min)、file_info(READ)配置合理
- 导出注册:
index.ts导出 +main.ts注册齐全(29 个工具) - 跨工具一致性:grep
(err as Error).message无匹配,错误处理统一无遗漏
六、修改文件清单(12 个)
文件 修改内容 package.json版本号 0.3.11 → 0.3.12 package-lock.json版本号 0.3.11 → 0.3.12(根 + packages['']) README.md版本徽章 0.3.11 → 0.3.12 electron/main.ts注册 FileMoveTool + FileInfoTool electron/harness/sandbox/permissions.ts新增 file_move / file_info 权限策略 electron/harness/tools/built-in/index.ts导出 FileMoveTool / FileInfoTool,注释更新至 29 个工具 electron/harness/tools/built-in/file-guard.ts新增 decodeBufferWithDetection / matchAnyGlob / 扩展 extractErrorMessage electron/harness/tools/built-in/filesystem.ts7 个工具全面优化(read/write/list/search/delete/move/info) electron/harness/tools/built-in/file-editor.ts新增 find_replace / multiline regex / backup,regex bug 修复 electron/harness/tools/built-in/code-search.ts统一 safeResolvePath + 外层 try-catch + extractErrorMessage electron/harness/tools/built-in/diff-viewer.tsUint16Array 内存优化 + safeResolvePath + 智能编码 + 错误处理统一 electron/harness/tools/built-in/git.tsgit_commit amend 模式 message 可选 + --no-edit 变更统计:588 insertions(+), 102 deletions(-)
七、工具数量变化
类别 v0.3.11 v0.3.12 变化 文件系统工具 5(read/write/list/search/delete) 7(+file_move/file_info) +2 文件编辑工具 1(file_editor) 1 - 代码搜索工具 1(code_search) 1 - 差异对比工具 1(diff_viewer) 1 - Git 工具 4(status/diff/log/commit) 4 - 文件/代码类小计 13 15 +2 工具总数 29 31 +2
八、设计权衡说明
本次实施中有以下设计权衡(非 bug,符合规范):
1. file_editor 仍用 readFile('utf-8') 而非 decodeBufferWithDetection
原因:这是正确的设计选择。
readFile('utf-8')会保留 UTF-8 BOM 字符,编辑后写回时 BOM 自动保留- 若改用
decodeBufferWithDetection,BOM 会被剥离,写回时 BOM 丢失 — 反而破坏文件 - 对 GBK/UTF-16 文件,建议用户先用
write_file转码再编辑
2. file_move overwrite 模式边缘风险
说明:
overwrite=true且目标已存在时,先删除目标再 rename。若 rename 失败(如跨文件系统 EXDEV、源文件被锁定),目标已被删除。实际影响:低。工作空间内文件通常在同一文件系统,rename 失败概率极低。源文件仍在原位置(只有目标丢失)。修复会增加复杂度(rename-to-tmp + rename + cleanup 三步序列),暂保持现状。
3. code-search searchWithRipgrep 保留 err.stderr || err.message
原因:子进程错误的关键信息在 stderr,
err.stderr || err.message是 stderr 优先语义,符合子进程错误处理惯例。未统一为extractErrorMessage(err, true)避免冗长。
九、升级须知
升级步骤
- 拉取最新代码:
git pull origin master - 安装依赖(无新增依赖,可跳过):
npm install - 重启应用(使新工具注册生效)
兼容性
- 完全向后兼容:所有既有工具的 API 参数均向后兼容(新增参数均为可选)
- 新增工具自动可用:
file_move/file_info已在main.ts中注册,无需额外配置 - 权限策略自动生效:
permissions.ts已配置默认策略,无需手动修改
建议测试场景
- 大日志文件
tail读取 - GBK / UTF-16 旧文件
read_file解码 file_move跨目录移动 + overwrite 覆盖find_replace替换含正则元字符的代码片段file_editormultiline regex 替换多行代码块backup: true编辑后检查 .bak 文件file_info查询文件元信息
十、提交信息
commit 058ee2d feat: 升级至 v0.3.12 — 文件与代码类工具全面优化(16 项) 12 files changed, 588 insertions(+), 102 deletions(-)
玥玥 · 2026-07-21
Downloads
- 强制 regex 含