`ull install` / `ull java` / `ull pack` 此前各自 `DownloadEngine::new(EngineConfig::default(), …)`: 用户在设置里配的 `download.concurrency` / `retry_limit` / `gh_proxy` 一概不生效;M193 把出厂并发 从 64 改成 8 之后,它们还静默跟着降了。现在三处都经 `crates/cli/src/download.rs::engine(ctx)`: - core:`shared/tuned.rs` 新增 `engine_with_tuning(cache_root, tune)` = `set_tuning` + `engine_for`, 由 `shared.rs` 重导出;`engine_for` 的签名与行为一字未改(presenter 的两步语义原样保留)。 放子模块是为了不动 `engine.rs`(那是 400 行零余量),`shared.rs` 仍 398 行。 - CLI:`download::tuning(ctx)` 用 `SettingStore::load(ctx.launcher_config(), launcher_schema())` 读 三个键(与 `ull config set` 同一份文件),默认值/夹取/回落在 `DownloadTuning::from_settings`; 键缺失或坏值静默回落出厂值,`engine()` 没有错误通道,安装不会因此中断。 - 顺带:`ull update` 复用 `install::build_engine`,也随之吃到设置。 - 测试:`crates/cli/src/download/tests.rs` 三条命令各一条(读 `config().max_concurrency` 与 `concurrency_probe()` 的真实值)+ 一条「缺失/越界/负数/类型不对 ⇒ 静默回落出厂值」; `shared/tuned.rs` 两条守住「灌调优与取引擎是一步」。变异实测:pack 换回裸 `EngineConfig::default()` ⇒ 只有 pack 那条红(left 8 / right 2)。
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 开发中。