You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
摘要
str_replace_editor工具的str_replace/insert会静默剥掉 UTF-8 BOM:读路径readText用TextDecoder("utf-8", { fatal: true })解码(默认剥离 BOM),编辑后writeText把无 BOM 的内容写回——带 BOM 的文件被编辑一次后 BOM 永久丢失。依赖 BOM 识别编码的工具(记事本、旧版 PowerShell、部分解析器)对处理后的文件可能误判编码。复现步骤
EF BB BF),例如用记事本"另存为 UTF-8"保存一个脚本文件。str_replace_editor的str_replace(或insert)修改该文件。EF BB BF已消失(BOM 被剥掉)。根因(源码定位,rc.6)
编辑路径是"解码-重写" —
@deepseek-ai/dsh-tool-str-replace-editor/lib/index.js:const before = await ctx.fs.readText(target, exec.signal);→ L171:ctx.fs.writeText(target, before.slice(0, offset) + newValue + before.slice(...));const lines = (await ctx.fs.readText(target, exec.signal)).split("\n")→ L211ctx.fs.writeText(target, after, ...)—— 两个命令都以"解码后的文本"为基准写回,BOM 一旦在解码层被剥就永远回不去。解码层默认剥 BOM —
@deepseek-ai/dsh-fs-local/lib/index.js:decodeUtf8:new TextDecoder("utf-8", { fatal: true }).decode(buffer)——TextDecoder默认ignoreBOM: false,解码时剥离 BOM(不产生\uFEFF字符);readWholeText→ 该解码;L779-797writeText直接写回字符串内容,无任何 BOM 恢复逻辑。实证(本机 Node 复刻同款解码):
TextDecoder("utf-8",{fatal:true})解码EF BB BF前缀文件 → 文本不含\uFEFF(BOM 被剥);ignoreBOM: true→\uFEFF保留;EF BB BF—— BOM 永久丢失。建议修复
方案 A(推荐)· 解码保留 BOM 字符:
decodeUtf8改用new TextDecoder("utf-8", { fatal: true, ignoreBOM: true })——BOM 作为\uFEFF字符进入文本流,编辑后原样写回(BOM 被当作内容的一部分保留)。一行级改动;代价是模型可见文本首字符为\uFEFF(渲染层通常不可见,可接受)。方案 B · 写回时按原文恢复 BOM:
readText记录原文件是否带 BOM(或由 fs 层在 edit/write 时检测原文头字节),writeText在原文带 BOM 且新内容不带时前置 BOM。模型侧文本保持干净(无\uFEFF),改动稍大(需在 fs 层透传标志)。方案 C · 字节级编辑:编辑路径基于
readBytes的字节偏移而非解码文本(BOM 是前 3 字节,天然保留)。改动最大,但对编码敏感文件最稳妥(顺带覆盖非 UTF-8 场景)。影响
环境
验证材料
TextDecoder参数(fatal:true)解码 BOM 文件 → BOM 被剥;ignoreBOM:true→ 保留;编辑写回后文件头不再为EF BB BF;dsh-fs-local/lib/index.jsL313-321/L351-357/L779-797 与dsh-tool-str-replace-editor/lib/index.jsL164/L171/L195/L211。First analysis of discussion #1022. Happy to open a PR with fix option A.
All reactions