# 开发工具配置:为什么关掉 pi-lens 的自动改写 本仓库**明确关闭** pi-lens 的项目级自动格式化与 autofix。这份文档记录原因, 配置本身在 `.pi-lens.json`(根目录)。 ## 一句话 pi-lens 编辑任一文件后会「安全格式化」它,而它的默认格式化器与本仓库的手工排版 不兼容 —— 每次编辑都会产生与内容无关的大面积 diff,把真正的改动埋掉。 已经造成过两次**真实损失**。 ## ⚠️ `.pi-lens.json` 必须是严格 JSON pi-lens 的配置加载是: ```js // pi-lens dist/index.js PROJECT_CONFIG_BASENAMES = ['.pi-lens.json', 'pi-lens.json']; // 没有 .jsonc function parseConfigFile(configPath) { const text = fs.readFileSync(configPath, 'utf-8'); raw = JSON.parse(text); // ← 不做去注释处理 } // 解析失败 → 打一行警告,然后**整份忽略** ``` 所以**带 `//` 注释会让这份配置完全失效**,而失败方式是静默的: 进程照常跑,只有启动时一行 `[pi-lens] ignoring invalid project config`。 这个坑真的踩过:第一次写这份配置时把大段理由写成了 `//` 注释, 于是「已经关掉了」这个结论是假的 —— 防护从一开始就没生效。 现在理由放在本文件里,JSON 里只留一个 `$comment` 指针。 ## 为什么必须关 pi-lens 在编辑文件后会走 smart-default 回退选择格式化器(见它的 `FORMATTER_POLICY_BY_EXTENSION`): | 扩展名 | 默认格式化器 | |---|---| | `.ts` `.tsx` `.js` | biome(默认 tab 缩进 + 双引号) | | `.html` | prettier(双引号、`` 变小写、按 80 列折行) | 两套默认值都与本仓库的排版冲突。两次已发生的损失: 1. **`19a3161`**:`git add -A` 把约 7000 行 biome 重排扫进了功能提交, 那次提交无法审查(还掩盖了一处 Go 文件的删行)。 2. **`a404cba`**:prettier 改写了 `client/electron/index.html` —— 单引号变双引号、 DOCTYPE 变小写,直接打破 `test/theme.test.mjs` 的两条断言(该测试要求 同步内联脚本里是 `classList.add('dark')`,单引号)。 ## 为什么不是「把格式化器配成本仓库风格」 试过:把缩进、引号、lineWidth 全部对齐之后,`biome format --write` 仍然改动 17 个文件 —— 本仓库的注释按语义换行、数组与调用按可读性手工折行, 这些格式化器还原不了。 ## 谁在守着这个仓库的格式 不是格式化器,是这些: - `tsc --noEmit`(前端类型) - `go vet` / `gofmt -l`(Go) - tree-sitter / ast-grep(pi-lens 的结构规则与安全规则,**只读、不改写**) - 各包的测试套件(`npm test`、`go test ./...`、`node --test`) ## 相关 - `biome.jsonc`:只挡得住 biome,**挡不住 prettier** —— 两者是并列的候选格式化器, 各有各的配置。所以真正的开关是 `.pi-lens.json`,它两条改写路径一起关。 ## 部署残留清理(`deploy/prune-deploy-artifacts.sh`) 部署会留下两类持续增长的东西:网关旧二进制(每份 ~24MB)与插件快照(opencode/dsh 的 快照含 node_modules,一份几十 MB)。2026-09-14 实测 `/opt/agentmail` 累计到 **1.3GB**, 其中旧二进制 ~790MB、快照 ~540MB。 ```bash bash deploy/prune-deploy-artifacts.sh # 干跑,只报告 bash deploy/prune-deploy-artifacts.sh --apply # 真删(默认:网关留 3 份、每插件留 3 份快照) bash deploy/prune-deploy-artifacts.sh --self-check # 判据自检(16 项,两侧都验) ``` 三条硬规矩:**保留回滚窗口**(发布纪律要求有回滚目标,所以不是全清);**绝不删正在使用的 快照**(扫 /proc 的 cmdline 与 cwd,命中就跳过 —— 删掉它进程一重启就找不到自己的代码); **在线数据库永不入列**。 注意那个"在用"判断必须排除**本进程及其祖先链**:调用方常把路径写在命令行里, 不排除就会出现"永远判为在用"(与 `pkill -f` 杀掉自己那条命令同一个坑,已写进脚本注释)。 ### 四类残留与各自的窗口 | 类别 | 来源 | 窗口 | |---|---|---| | 网关旧二进制 `agentmail-gateway.bak-` | `redeploy-gateway.sh` | 保留最新 3 份 | | 插件快照 `/` | `redeploy-plugin.sh` | 每插件保留最新 3 份,`current` 永远保留 | | 数据库/附件**备份集** `backups/agentmail-.db` + `attachments-.tar.gz`、`data/agentmail.db.bak-` | `reset-demo.sh` 与早期手工留档 | 保留最新 1 集 | | `/tmp/agentmail-pre-deploy-*.db`、`/tmp/agentmail-pre-prune-*.db` | `redeploy-gateway.sh`、`prune-test-sessions.sh` | 各保留最新 2 份 | 同一个 `` 的库与附件包算**一个备份集**,一起进出窗口 —— 拆开留没有意义。排序按 **文件名里的时间戳**而不按 mtime:09-02 的两份备份被 09-08 的一次"打开看一眼"改了 mtime, 按 mtime 排会把最老的判成最新的。**没有时间戳的文件一律不碰**(判定不了就不删)。 `pre-prune` 那份是会话归档(不可逆操作)唯一的回滚点,所以它单独一条窗口、报告里也写明身份。 ### 三条判据,以及它们各自防的那个错 1. **在线库不入删除清单**(`del()` 里的 `readlink -f` 比对):备份删错能重建,在线库删错回不来。 2. **每个插件至少留一份"上一版"**:只有 `current` 时脚本报 `⚠ 无回滚目标`。它只报告、 **不造快照** —— 造不出来的东西不该假装有。(2026-09-14 那次事故就是这么暴露的: 四个插件各只剩 `current`,回滚目标没了。) 3. **`--self-check` 两侧都验**:干净样本该删的删、该留的留、在线库不动必须是绿的; 把窗口外的备份换成**指向在线库的符号链接**,脚本必须**拒跑**(退出码 1), 不是"删了才发现"。最后一条是"自检没有碰生产根":比对前后 `/opt/agentmail` 的清单指纹。 ### 事故记录:自检把生产当成了沙箱(2026-09-14) `--self-check` 第一版用 `ROOT="$t" … bash "$0"` 传假根。脚本读的是 `AGENTMAIL_ROOT`, 于是这个前缀赋值被静默忽略,自检的 `--apply` 打在了**生产根**上,删掉一批回滚备份 (3 个旧网关二进制、8 个插件快照、09-02 的两组备份集)。 **为什么没被发现**:`PRUNE_TMP_DIR` 那一路的变量名是对的,所以输出的 `/tmp` 段看着"确实是假根", 干跑那一轮的报告也像模像样 —— 半对的状态比全错更难认。是 `bash -x` 里那行 `ls -1t /opt/agentmail/…` 露的马脚。 **改法不是"下次小心"**:① 传对变量名;② 自检的根目录必须在临时区,否则拒跑; ③ "自检不碰生产"进判据(前后指纹比对)。这条与 `pkill -f` 杀自己同类: **安全装置自己出错时,产出的是一份看着正常的报告**。