Win encoding doctor
Skill Ludi-Herry/win-encoding-doctor/skills/win-encoding-doctor
Windows 中文/非 ASCII 编码问题的分层诊断与修复。症状触发:乱码、中文变 ??、UnicodeEncodeError、0 字节文件、多出 BOM(ef bb bf / ff fe 文件头)、批量替换报成功但文件没变、"在 agent 里正常、换个终端就坏";主动触发:体检/加固 Windows 编码环境、新机器配中文链路。只要用户在 Windows 上报这类症状就用本 skill,别裸猜。负面边界:非 Windows 平台不适用;单纯改字体/显示渲染问题不归这里;写文件必带 -Encoding 之类的日常纪律由 hook 与 AGENTS.md 管,本 skill 管"出事后定位哪层坏了并根治"。From its SKILL.md
npx -y skills add Ludi-Herry/win-encoding-doctor --skill win-encoding-doctorAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.1 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
win-encoding-doctor
Windows 编码问题从来不是一个 bug,是一条链上某一层坏了。本 skill 的方法:先分层定位,再修根,最后字节级验证。跳过定位直接堆修复(到处 chcp、加 try/except、换字体)只会把症状搬家。
四条铁律
- 只信字节,不信终端显示。 终端会用自己的编码渲染,看起来正常不等于字节正常。一切验证落到十六进制:UTF-8 的"中文" =
e4 b8 ad e6 96 87;文件头ff fe= UTF-16LE;ef bb bf= UTF-8 BOM;3f 3f= 已经不可逆地变成??。 - 修根不修表。 修复阶梯从系统级到程序级排过序(见 fix-ladder),能在更根部修的不要在叶子上打补丁。给每个 Python 脚本包 try/except 是表;系统代码页 65001 是根。
- 环境状态有时效。 改完 env var / profile / 系统代码页,已经开着的进程吃不到,必须重开进程再验证;反过来,报告"还是坏的"之前先确认测试进程是新起的。
- 结论是宿主相对的。 同一台机器,pwsh / PS 5.1 / 带不带 profile / agent 工具 shell 可以给出完全不同的答案(实测:三个宿主三个结果)。不带 L0 指纹的结论等于没验证——报告必须注明"在哪个宿主、哪种启动方式下测的",且永远不要从你所在的宿主外推其他宿主:Windows 自带的 5.1 一直都在,用户的自动化可能带
-NoProfile。
工作流
第 0 步:读本机状态(如果有)
先看 references/this-machine.md。状态文件的作用是缩短修复检索、提供历史对照(上次的剩余坑、备份位置、时间线),它不能替代复验——重启、系统更新、应用更新都可能引入回归(本机的 936 回归就发生在"全绿"记录之后)。体检类请求永远重跑诊断脚本;症状类请求可先按状态文件里的"已知坑"对号,但下结论前要有本次实测证据。文件不存在 = 新机器,走完整诊断。
第 1 步:跑分层诊断(自带 L0 环境指纹)
pwsh -File <本 skill 目录>/scripts/diagnose.ps1
脚本只读(临时文件写在 %TEMP%),先输出 L0 环境指纹,再逐层输出 PASS / WARN / FAIL / SKIP,退出码 = FAIL 数。
L0 指纹(每条结论都要带着它):OS 版本与 build、ACP/OEMCP(=UTF-8 Beta 勾选状态)与 locale、实际 chcp、当前宿主与是否 -NoProfile、机器上有哪些宿主(pwsh/5.1/cmd)、Python 与 PYTHONUTF8 状态、agent 环境痕迹与版本、执行器写探针。写探针失败说明当前执行器(hook/沙箱)拦截文件写入——把受影响的层标注"当前执行器无法验证",换宿主补测,别把执行器限制误诊为编码故障(gotchas #13)。
| 层 | 查什么 | 坏了的典型症状 |
|---|---|---|
| L1 系统代码页 | 注册表 ACP/OEMCP 是否 65001 | Python 崩 UnicodeEncodeError、老程序乱码 |
| L2 console/管道编码 | Console In/Out 编码、$OutputEncoding 有无 BOM 前导 | 管道给原生程序的 stdin 开头多 ef bb bf、中文变 ?? |
| L3 Python 层 | 裸跑输出中文 + stdout 编码 | 'charmap' codec can't encode |
| L4 管道字节(PS→原生) | 中文经管道进原生程序的真实字节 | BOM 污染、mojibake |
| L4b 捕获完整性(原生→PS) | 原生 UTF-8 输出捕获进 PS 变量后是否完好 | 变量已损但显示看着正常(二次编码回转骗人) |
| L5 PS 5.1 默认写文件 | > / Out-File / Set-Content 三种写法的字节头 | 写出 UTF-16LE 被下游按 UTF-8 读 |
| L6 profile 覆盖 | 两个 PowerShell profile 是否有 no-BOM UTF-8 初始化 | "agent 里正常、裸终端坏" |
第 2 步:按症状直达(不必每次全跑)
用户报着火点明确时,直接对号入座再跑对应层确认:
UnicodeEncodeError: 'charmap'/ cp1252 / cp936 → L3/L1,修 PYTHONUTF8 或系统代码页- 替换/正则"成功了但文件没变" → 大概率不是编码是 CRLF(.NET 正则
$不匹配 CRLF),见 gotchas #2 - stdin/文件开头多
ef bb bf→ L2,profile 的编码对象带了 BOM 前导,注意 InputEncoding 也要设(gotchas #3、#4) - 文件
ff fe开头 / 记事本正常别处乱码 → L5,PS 5.1 写的 UTF-16LE - "Claude/codex 里好好的,自己开终端就乱" → L6,harness 给了 console UTF-8 而裸终端没有
- 工具打印 ✓/emoji 当场崩但文件都写完了 → L3,只是收尾打印崩,别误判任务失败(gotchas #1)
第 3 步:修复(读 fix-ladder 再动手)
按 references/fix-ladder.md 从对应层的梯级修。原则:用户级改动(env var、profile)先备份可直接做;系统级改动(UTF-8 Beta)必须先向用户说明副作用并拿到同意——它会让极少数硬编码 GBK/ANSI 的老软件乱码,且需重启。
第 4 步:字节级复验
修完重跑第 1 步(新进程!),逐层核对到绿。管道验证的标准姿势:
'中文Pipe' | python -c "import sys; d=sys.stdin.buffer.read(); print(d.hex())"
# 期望 e4b8ade69687...,开头不得有 efbbbf
第 5 步:更新本机状态
把新状态(日期、各层结果、剩余已知坑、备份文件位置)写回 references/this-machine.md,下次直接短路。
输出契约
诊断/修复报告必须包含,缺一项不算完成:
- L0 指纹块(宿主、启动方式、系统状态)——结论只对该指纹成立;
- 分层结果表(含本次没跑的层,标注为什么跳过);
- 症状 → 根因(指向具体层和 gotcha 编号);
- 处方(fix-ladder 梯级 + 副作用 + 回滚方式);
- 新进程里的字节级复验证据(十六进制/命令输出原文);
- 未能验证项及原因(执行器拦截、宿主缺失等)——如实标注"无法验证",不要留空也不要猜。
完成标准:每个 FAIL 要么有"修复 + 新进程复验通过"的记录,要么明确标注"当前执行器无法验证 + 原因 + 建议的补测宿主"。
Gotchas(真实翻车案例,先读再修)
见 references/gotchas.md——每条都是实测踩过的:BOM 的真实来源、CRLF 静默失败、PS 5.1 三种写法三种编码、脚本文件自身编码的坑等。新翻车往里追加(症状 → 根因 → 修法),不要加长本文件。
What ships with it: 4 files
23.3 KB alongside SKILL.md, 1 of them executable
references/
- fix-ladder.md3.7 KB
- gotchas.md7.7 KB
- this-machine.template.md1019 B
scripts/
- diagnose.ps1runs10.9 KB