# 我上次的修复只做了一半
上一次(429149e)我加了根 biome.jsonc,把 biome 的 formatter 关掉,并撤销了它造成的
约 7000 行重排。那时我以为问题解决了 —— **没有**。
pi-lens 编辑文件后会「安全格式化」它,格式化器是**按扩展名各自挑**的
(FORMATTER_POLICY_BY_EXTENSION)。仓库里没有任何格式化器配置时它走 smart-default 回退:
.ts/.tsx/.js/.mjs/.json/.css → biome
.html → prettier ← 这一条我漏了
biome.jsonc 挡得住 biome,对 prettier 完全无效。于是 a404cba(图标提交)里我改了
index.html 加 favicon,prettier 顺手把它改写了:
-<!DOCTYPE html> +<!doctype html>
-classList.add('dark') +classList.add("dark") ← 单引号变双引号
-<meta name="viewport" …> +多行折行
而 test/theme.test.mjs 恰好逐字符断言那一段里是 `classList.add('dark')`(单引号),
两条断言当场变红。**更糟的是我没看见**:验证时我用 `grep -E 'Test Files|Tests |FAIL'`
过滤输出,而这个测试的摘要是中文的(「主题:28 通过,2 失败」),被整行滤掉了,
于是我在提交信息里写了「196 项测试全绿」—— 一句不成立的结论。
(顺带厘清两起事故的元凶不同:19a3161 那次是 **biome**(tab 缩进是它的默认),
a404cba 这次是 **prettier**。我先前把它们当成同一个问题。)
# 根因级修法
不再逐个格式化器打补丁,而是关掉 pi-lens 对本仓库的改写路径。
项目级 `.pi-lens.json` 支持 format.enabled / autofix.enabled(文档
docs/settings.md 的 mutation controls),由当前目录向上查找,覆盖整个仓库:
{"format": {"enabled": false}, "autofix": {"enabled": false}}
autofix 一并关掉:它同样会在与本次改动无关的行上动手。
biome.jsonc 保留(纵深防御,且它顺带关掉了 biome 的自动修复)。
# 验证
- 修好 index.html:DOCTYPE 恢复大写、viewport 回单行、内联脚本回单引号,
与 19a3161^(未受污染的原版)逐字节一致,只多出 favicon 四行。
实验证据:把原始版喂给 prettier,输出与 a404cba 里的版本**逐字节相同** —— 确认元凶。
- `node test/theme.test.mjs` → 主题:30 通过,exit 0
- 加注释后再编辑一次 index.html:单引号与 DOCTYPE 均未被改写(改写路径已断)
- 顺带在注释里写明「引号别统一成双引号,theme.test.mjs 逐字符断言」,防止后人"清理"
55 lines
2.4 KiB
HTML
55 lines
2.4 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content" />
|
||
<!--
|
||
图标放在 public/assets/ 而不是 public/ 根下:Gateway 只把 /assets/* 和 /
|
||
挂给了静态处理器(见 server/cmd/server/main.go 的静态段),放在根下会 404。
|
||
Vite 原样拷贝 public/ 到 dist/,所以开发态与内嵌后 URL 都是 /assets/…。
|
||
品牌源文件与其生成脚本:client/electron/src/icons/。
|
||
-->
|
||
<link rel="icon" type="image/svg+xml" href="/assets/agentmail.svg" />
|
||
<link rel="alternate icon" type="image/x-icon" href="/assets/favicon.ico" />
|
||
<link rel="apple-touch-icon" href="/assets/apple-touch-icon.png" />
|
||
<meta name="theme-color" content="#2563eb" />
|
||
<title>AgentMail</title>
|
||
<script>
|
||
/*
|
||
* 首帧防闪屏。
|
||
*
|
||
* JS bundle 有几百 KB,从 HTML 解析完到 React 挂载之间有一段空窗 ——
|
||
* 那段时间里页面是 body 的默认底色。深色偏好的用户会被闪一下白屏,
|
||
* 而且是每次刷新都闪。
|
||
*
|
||
* 这段脚本必须**内联且同步**:外链或 defer 都会晚于首次绘制。
|
||
* 逻辑与 themeStore 的 readStored/resolveTheme 一致,
|
||
* 改那边的键名或取值时这里要同步。
|
||
*
|
||
* 引号别「顺手统一」成双引号:test/theme.test.mjs 逐字符断言这一段里是
|
||
* classList.add('dark')(单引号)。曾经被 prettier 改写过一次,直接让测试变红。
|
||
*/
|
||
(function () {
|
||
try {
|
||
var p = localStorage.getItem('agentmail.theme') || 'system';
|
||
var dark =
|
||
p === 'dark' ||
|
||
(p === 'system' &&
|
||
window.matchMedia &&
|
||
window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||
if (dark) {
|
||
document.documentElement.classList.add('dark');
|
||
document.documentElement.style.colorScheme = 'dark';
|
||
}
|
||
} catch (e) {
|
||
/* localStorage 不可用(隐私模式)时退回浅色,不阻塞渲染 */
|
||
}
|
||
})();
|
||
</script>
|
||
</head>
|
||
<body class="bg-gray-50 text-gray-900 antialiased">
|
||
<div id="root"></div>
|
||
<script type="module" src="/src/main.tsx"></script>
|
||
</body>
|
||
</html>
|