D1(high):mirrors.json 的 bmclapi-libraries 少了 inject,官方 libraries.minecraft.net/<path> 被重写成镜像根 + <path>(BMCLAPI 的 maven 仓库挂在 /maven 下),实测 70/70 个库全 404、全部回落官方源(单请求 EMA 6.3 s)。本轮实测: guava:32.1.2-jre 无 /maven → 404 / 9 B;带 /maven → 200(2 次 302)/ 3041591 B, sha1 与官方逐字节一致。补法与 bmclapi-assets-objects 的 /assets 同一机制(inject), 不把 /maven 拼进 to(to 是镜像根)。 守卫两道,抓不同的东西: - 形态:凡 from 指向 maven 仓库的规则,to+inject 必须以 /maven 结尾(并点名覆盖的 5 条规则 id,删/改名都会红); - 行为:4 个真实官方 maven 根展开后必须逐字等于 /maven/<子路径>。 原有 prefix_rule_preserves_sub_path 的期望值曾把 D1 的 bug 钉成期望,一并改正。 变异(删掉 inject)实测三条同时红,恢复后 mirrors 14 passed。 D11(low):进度回调只累加「处理到第几个文件」,还打「下载 {done}/{total}」, 重装同版本(全部已就绪)时会连打 3961 行「下载」而一个字节都没下。拆出 install/progress.rs:计数全部来自 FileOutcome.status(Downloaded/Skipped/Failed), 下载数为 0 时人读行不出现「下载」二字(改说「已就绪 d/t(跳过 N 个)」),--json 的 progress 事件补 downloaded/skipped/failed。用例构造 96 个全 Skipped ⇒ 断言每行都不含 「下载」且末行为「已就绪 96/96(跳过 96 个)」;变异(退回旧文本)实测红。 其它镜像表(assets / jar / version_manifest / 索引 / fabric / forge)的 inject 形状 实测一致,另有 liteloader 目标路径 404、quilt maven 无规则两条【不同类】观察, 不在本轮范围,报告里交回 tower。
r1 把 `rename` 套在**插值后的整条文本**上,于是用户数据被改坏:账户名恰好是 `ull` 会变成 `unlucky-launcher`,路径 `D:/tmp/ull/.ULL/...` 会变成 `D:/tmp/unlucky-launcher/.ULL/...`, 回显的子命令 `ull` 也会被改名。 改成模板占位符:文案里写 `%prog%`,**只在渲染时**(print_report / print_error / 帮助)替换成 argv[0] 的 basename。占位符只存在于静态模板里,插值进来的账户名 / 路径 / 子命令碰不到它。 用 `%prog%` 而不是 `{prog}`:这些模板要活在 `format!` 里,`{prog}` 会被 format! 当成参数名 编译失败。 同时补上 r1 漏的反方向:**stdout 的正常输出**(Report.human 与 warnings)现在也做替换, 以前只有 stderr 的错误做了,两边不一致。 回归测试:`user_data_that_says_ull_is_never_rewritten` 断言「账户名 `ull`」「路径 `\ull\`」 「未知命令 `ull`」在 fill 之后逐字不变。 占位符替换覆盖 21 个文件的 63 处文案;测试夹具里形如 `ull-mcp-diagnose-<pid>` 的临时目录名 已回滚为字面量(那不是文案)。
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent), MCP server 接入外部 Agent 工具,GUI 开发中。