From 1315b37f62caea95a493b326de3c91e4efd213bd Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 5 Nov 2026 11:36:39 +0800 Subject: [PATCH] =?UTF-8?q?docs(readme):=20=E7=8A=B6=E6=80=81=E6=AE=B5?= =?UTF-8?q?=E6=94=B9=E6=88=90=E5=BD=93=E5=89=8D=E4=BA=8B=E5=AE=9E=EF=BC=8C?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=9C=B0=E5=9B=BE=E8=A1=A5=E9=BD=90=E4=B8=89?= =?UTF-8?q?=E4=B8=AA=20crate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 状态段原来停在「iced 版每个页面都是占位」——早就不成立了。改成: 十四页功能已齐、文案跟随系统语言、外观三件套、整合包导入导出与安装选项, 以及明确列出「还没做」的四项(安装器与自动更新、macOS 定型复核、 逐文件冲突策略、原生文件选择框)。 模块地图补上 crates/presenter、crates/i18n、crates/palette-extract, 并写明分层:app-iced → presenter → core/agent,design 与 i18n 不得反向依赖渲染框架。 --- README.md | 130 +++++++++++++++++++++--------------------------- README.zh-CN.md | 57 +++++++-------------- 2 files changed, 76 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index a6c56be..e391c68 100644 --- a/README.md +++ b/README.md @@ -15,86 +15,66 @@ attached to other agent tooling as an MCP server. - **Single-file native binary**: the launcher itself needs no JVM, no WebView and no sidecar runtime. The JDK a game needs is downloaded and managed per instance, not as a launcher dependency. -- **One UI stack in the build**: the UI is iced 0.14 + Material 3 Expressive. The earlier Slint - implementation (`crates/app`) is kept as source-only history: it is excluded from the cargo - workspace, so the workspace never builds, tests or ships it. v0.1.0 — the only tagged release so - far — still carries a Slint build (see Status). -- **CPU software-rendering fallback**: `--software-renderer` keeps the interface rendering - normally on machines with no usable GPU or with broken drivers. -- **AI agent + MCP**: chat, setting edits and crash diagnosis inside the launcher; `ull agent - serve` exposes the same core as an MCP server (stdio or Streamable HTTP) to external agent tools. -- **Mod loaders**: Fabric, Quilt, NeoForge, Forge, with modpack and CurseForge / Modrinth clients in - the core. +- **One binary, two shapes**: the GUI binary also answers every CLI subcommand before any UI code + runs — no window, no renderer probe, no font scan. A second, lighter `ull` artifact serves the + same command set from a binary that links no graphics stack at all. +- **One UI stack**: iced 0.14 + Material 3 Expressive, with self-drawn title bar, animated + navigation rail, light / dark / follow-system, and a background-image colour pipeline. The earlier + Slint implementation (`crates/app`) is kept as source-only history: excluded from the cargo + workspace, never built, tested or shipped. +- **CPU software-rendering fallback**: `--software-renderer` keeps the interface rendering normally + on machines with no usable GPU or with broken drivers; the backend probe falls back on its own when + no adapter is usable. +- **AI agent + MCP**: chat, setting edits and crash diagnosis inside the launcher; `ull agent serve` + exposes the same core as an MCP server (stdio or Streamable HTTP) to external agent tools. The + agent rail runs on real presenter state, and says so plainly when no model endpoint is wired. +- **Mod loaders and modpacks**: Fabric, Quilt, NeoForge, Forge; CurseForge manifest, Modrinth + `.mrpack` and MultiMC/Prism packs import, plus mrpack / CurseForge export. - **Java management**: a Temurin → Oracle → Microsoft → Zulu fallback chain, region-aware. -- **Accounts**: sign in with a Microsoft account over OAuth 2.0 device code flow → Xbox Live → - XSTS → `api.minecraftservices.com`; account tokens are kept on this machine only. +- **Accounts**: Microsoft sign-in over OAuth 2.0 device code flow → Xbox Live → XSTS → + `api.minecraftservices.com`; third-party community auth servers; local offline profiles for + isolated testing. Account tokens are kept on this machine only. - **Engine**: multi-source download (health scoring, mirrors, chunked transfers, hash while downloading) and a YAML rule-based crash diagnosis engine. - **License**: Apache-2.0 © AskaEth (YeiJ). ## Status -Two tracks. They are not the same product yet, so read the headings before downloading anything. +`v0.1.0` (2026-11-01) is the only tagged release so far and it predates the UI rewrite: its assets +are Slint builds. Everything described below lives on the development line and is what the release +pipeline now builds. -### Track A — historical: v0.1.0, Slint UI (the only tagged release so far) - -> **Historical implementation — no longer in the default build or the release matrix.** The Slint -> tree (`crates/app`) is kept in the repository as source-only reference: it is excluded from the -> cargo workspace, so `cargo build` / `cargo test` / `cargo clippy` never touch it and no artifact is -> built from it. Read the source if you want to see how that UI was put together; do not expect to -> build it. The list below is kept because it records what the v0.1.0 assets actually contain — -> since v0.1.0 the pipeline builds the iced binary and ships it under the same public asset names. - -- **GitHub Releases `v0.1.0`** (2026-11-01, flagged pre-release): single-file assets for Windows - x64 (a bare `.exe`), Linux x64 and macOS (arm64 and x64) `.tar.gz`. Every release also carries - `SHA256SUMS.txt` and the `LICENSE` / `NOTICE` / `README.md` texts as separate assets; on Windows - those texts sit next to the `.exe` because a bare exe cannot hold them, while the unix archives - already contain them. -- **UI**: Slint + Metro. This is the shipped GUI — the instance, download, account, Java, log and - settings pages all run on the core engine (the in-app AI chat panel is a scripted placeholder). -- **CLI in the same binary**: `unlucky-launcher instances list`, `unlucky-launcher launch `, - `unlucky-launcher logs ` and the rest of the command set run before any UI is built — no - window, no renderer probe, no font scan. Commands: `instances`, `install`, `launch`, `accounts`, - `sessions`, `logs`, `diag`, `config`, `java`, `agent`, plus `--help` / `--version`. -- **A second, lighter artifact `ull`** (`cargo build --release --bin ull`, zero UI dependencies): the - same command set from a binary that links no graphics stack at all — not even fontconfig. Servers, - CI containers and Termux get `ull`; desktops get `unlucky-launcher` and one binary covers both GUI - and CLI. Both are release assets from the next tagged release (the `v0.1.0` assets predate this). -- Windows ARM64 and Linux ARM64 slots are wired into the release pipeline; the next tagged release - builds them. The `v0.1.0` assets predate those two slots. - -### Track B — in progress on `dev`: next-generation UI (iced + Material 3 Expressive) - -**This track is not released yet — you can see it only by building from source.** - -- **Locked direction**: the look is Material 3 Expressive and the framework is iced 0.14; the UI - layer is written from scratch. Neither the style nor the framework will change again. -- **Done**: the token crate `crates/design` (no UI framework, no third-party crates — real HCT - color, type scale, shape scale, spacing, elevation, motion, icon geometry, per-component - metrics) and the skeleton crate `crates/app-iced` (opens a window, self-drawn title bar and - window buttons, navigation rail, colors and type taken from tokens only, GPU→CPU backend probe - with automatic fallback, and the screenshot/diff channel the visual reviews use). -- **Not done**: the component library (buttons, dialogs, lists, menus, search, and the rest of the - M3 set), page migration, and the i18n pass. Every page in the iced binary is a placeholder. -- **Slint is retired from the build, kept as reference**: `crates/app` is no longer a workspace member - (M118) — the source stays for historical reference only: not compiled, not tested, not shipped, and - no longer buildable as a workspace member. What is left of the flip is the *rename*: until the iced - build passes equivalence acceptance its binary is still called `unlucky-launcher-iced`, while the - release pipeline already ships it under the public `unlucky-launcher` asset name. +- **The iced UI is feature-complete**: fourteen pages — instances, version management (three-column + rail layout with search), content library (modpacks / mods / resource packs / shaders with source + and version filters), logs, settings (general / appearance / Java / downloads), accounts + (Microsoft device code, third-party community servers, local profiles), the AI rail and the + installer flows — on top of one component library and one token set. +- **Localisation follows the system language**: detection, an explicit override in settings, and + persistence across restarts. UI copy goes through a single message catalogue; there is no + hard-coded string in the view layer. +- **Appearance**: window background image, per-panel transparency and whole-window transparency + (Windows), light / dark / follow-system, and system window corners where the platform grants them. + On CPU rendering the translucent layers are switched off and the UI says so. +- **Packaging and the installer paths** (curseforge / modrinth / multimc import, mrpack and + CurseForge export, install options with loader selection and real cancellation) are in the build. +- **What is not done yet**: installers / auto-update channel; macOS re-verification on a real + machine after the Windows pass; per-file conflict policy on pack import (the import pipeline has one + global policy today, and the UI states that rather than pretending otherwise); a native file + chooser (import accepts drag-and-drop and a pasted path). Binaries you may run into, so you can tell them apart: | Binary | Crate | State | |--------|-------|-------| -| `unlucky-launcher-iced` | `crates/app-iced` (iced 0.14) | the only GUI binary the workspace builds; the release pipeline stages it under the public name `unlucky-launcher`; same subcommand dispatch | +| `unlucky-launcher-iced` | `crates/app-iced` (iced 0.14) | the GUI binary the workspace builds; the release pipeline stages it under the public name `unlucky-launcher`; the same binary answers every CLI subcommand | | `unlucky-launcher` | `crates/app` (Slint) | **historical**: that crate is excluded from the workspace, so this binary is no longer built or shipped; the v0.1.0 assets are the last Slint builds | | `ull` | `crates/cli` | the zero-UI build of the same command set, shipped as its own asset | -`unlucky-launcher` and `ull` are not duplicates. The GUI binary needs the graphics stack when it -opens a window (it `dlopen`s X11 / Wayland / GL, and links `libfontconfig` at load); `ull` needs -nothing beyond glibc, so it runs on a server, a CI container or Termux where no window can exist. -Pick `ull` when there is no desktop, `unlucky-launcher ` when there is. Both print the same -CLI text and name themselves after the binary you invoked: `unlucky-launcher --help` starts with +`unlucky-launcher` (the GUI) and `ull` are not duplicates. The GUI binary needs the graphics stack +when it opens a window (it `dlopen`s X11 / Wayland / GL, and links `libfontconfig` at load); `ull` +needs nothing beyond glibc, so it runs on a server, a CI container or Termux where no window can +exist. Pick `ull` when there is no desktop, `unlucky-launcher ` when there is. Both print the +same CLI text and name themselves after the binary you invoked: `unlucky-launcher --help` starts with `unlucky-launcher ·`, `ull --help` starts with `ull ·`. ### Subcommand dispatch @@ -123,7 +103,7 @@ The rule is deliberately narrow, so nothing that used to work changed meaning: **Unknown subcommands are an error, not a GUI launch**: `unlucky-launcher lst` prints "未知命令 `lst`", hints `unlucky-launcher --help`, and exits 1. Silently opening a window would tell a script that its typo took effect. The subcommand table itself lives in exactly one place — -`crates/cli/src/cli/parse.rs` — so both GUI binaries and `ull` accept the same set by construction. +`crates/cli/src/cli/parse.rs` — so both the GUI binary and `ull` accept the same set by construction. ## Module map @@ -131,8 +111,11 @@ a script that its typo took effect. The subcommand table itself lives in exactly Unlucky-Launcher (cargo workspace) ├── crates/core # domain library: zero UI dependencies, eight modules ├── crates/agent # AI agent: ToolSpec registry + built-in client + MCP server (one core, two shapes) +├── crates/presenter # business host layer: framework-free state / host / dto / conversion ├── crates/design # design tokens: real HCT color / type / shape / spacing / elevation / motion / icons │ # / component metrics — zero UI dependencies, no third-party crates +├── crates/i18n # language detection, message catalogue, CJK font policy +├── crates/palette-extract # the only crate that decodes images, for the wallpaper colour pipeline ├── crates/app # HISTORICAL Slint UI (bin `unlucky-launcher`): excluded from the workspace, │ # source-only reference — never built, tested or shipped any more ├── crates/app-iced # the iced UI (bin `unlucky-launcher-iced`): the only GUI the workspace builds @@ -140,6 +123,9 @@ Unlucky-Launcher (cargo workspace) └── packaging # single-file artifact matrix and release scripts ``` +Layering: `app-iced` → `presenter` → `core` / `agent`. `design` and `i18n` are consumed by the shell +and the presenter; none of them may depend on a rendering framework, and the guards enforce it. + The eight modules of `crates/core`: | Module | Responsibility | @@ -148,8 +134,8 @@ The eight modules of `crates/core`: | `download` | multi-source health scoring, mirrors, chunked downloads, hash-while-downloading | | `game` | version / instance repository, snapshots and inheritance resolution | | `launch` | 10-stage launch pipeline, processes, JSONL event stream | -| `auth` | Microsoft sign-in (OAuth 2.0 device code → Xbox Live → XSTS → Minecraft Services) | -| `addon` | mod loader installation, modpacks, CurseForge / Modrinth | +| `auth` | Microsoft sign-in (OAuth 2.0 device code → Xbox Live → XSTS → Minecraft Services), third-party community servers, local profiles | +| `addon` | mod loader installation, modpack import, CurseForge / Modrinth, pack export | | `diagnose` | five signal collectors, YAML rule engine, hs_err parsing | | `platform` | OS abstraction: paths, processes, file locks, capability probing, runtime OS detection | @@ -161,7 +147,7 @@ Prerequisites: `rustfmt` and `clippy` components) - Windows: MSVC toolchain (what CI uses) or MinGW-w64 (`x86_64-pc-windows-gnu`) - Linux: `libxkbcommon-dev libfontconfig1-dev libgl1-mesa-dev libegl1-mesa-dev libwayland-dev - libxcb1-dev` — winit + wgpu/tiny-skia ask for these at build time (the Slint build also needed femtovg) + libxcb1-dev` — winit + wgpu/tiny-skia ask for these at build time ```bash cargo fmt --all --check # formatting @@ -170,9 +156,9 @@ cargo test --workspace # tests cargo build --release # binaries land in target/release/ ``` -`--workspace` covers the eight members in the module map. `crates/app` is excluded at the workspace -level (M118), so none of these commands compiles the Slint tree — and there is no build command for -it: that crate is kept as source-only reference and can no longer be built as a workspace member. +`--workspace` covers the members in the module map. `crates/app` is excluded at the workspace level +(M118), so none of these commands compiles the Slint tree — and there is no build command for it: +that crate is kept as source-only reference and can no longer be built as a workspace member. What the build produces: @@ -208,7 +194,7 @@ a real runner. | Workflow | Content | |----------|---------| | `.github/workflows/ci.yml` | fmt + clippy + test + release build (Windows / Linux matrix); Linux runtime smoke (Xvfb: renders one real frame, then asserts the PNG is not blank); macOS runtime probe (manual dispatch only) | -| `.github/workflows/guards.yml` | zero-UI guard for `crates/core` (manifest plus `cargo tree`), 400-lines-per-file guard, cargo-deny license and source guard | +| `.github/workflows/guards.yml` | zero-UI guards (`crates/core`, `crates/presenter`, `crates/design`), 400-lines-per-file guard, cargo-deny license and source guard | | `.github/workflows/release.yml` | tag `v*` → per-slot builds → single-file artifacts + `SHA256SUMS.txt` → GitHub Release | ## Platform baseline diff --git a/README.zh-CN.md b/README.zh-CN.md index 9c0b194..f04e005 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -28,47 +28,23 @@ Unlucky Launcher(ULL)是一个用 Rust 写的免费开源 Minecraft: Java ## 当前状态 -两条轨道,还不是同一个东西——看小标题再决定下载什么。 +`v0.1.0`(2026-11-01)是目前唯一的 tag,它早于 UI 重写:那批资产是 Slint 版。下面说的这套东西在开发 +线上,也正是发布流水线现在会打出来的东西。 -### 轨道 A —— 历史:v0.1.0,Slint 版(目前唯一的 tag) - -> **历史实现——已不在默认构建与发布矩阵内。** Slint 那棵树(`crates/app`)作为源码参考留在仓库里: -> 已被 cargo workspace `exclude`,所以 `cargo build` / `cargo test` / `cargo clippy` 都不会碰它, -> 也没有任何产物从它构建。想了解那一版 UI 怎么写的就直接读源码——**不要再尝试构建它**(它的 manifest -> 整份是 workspace 继承写法,离开 workspace 后连解析都过不了)。下面这段原文保留,因为它记录的是 -> `v0.1.0` 资产里到底装了什么;从 `v0.1.0` 之后,流水线构建的是 iced 版,对外文件名不变。 - -- **GitHub Releases `v0.1.0`**(2026-11-01,标记为 pre-release):单文件产物覆盖 Windows x64(裸 - `.exe`)、Linux x64、macOS(arm64 与 x64)`.tar.gz`。每个 Release 另挂 `SHA256SUMS.txt` 与 - `LICENSE` / `NOTICE` / `README.md` 三份文本——Windows 是「一个 exe 装不下文本」所以并列挂出, - unix 归档里本来就装着。 -- **UI**:Slint + Metro。这是已交付的图形界面——实例、下载、账户、Java、日志、设置 - 各页都由 core 引擎驱动(应用内 AI 对话面板仍是脚本化的占位)。 -- **同一个二进制就是 CLI**:`unlucky-launcher instances list`、`unlucky-launcher launch <实例>`、 - `unlucky-launcher logs ` 等命令在任何 UI 代码之前分流——不开窗、不探渲染后端、不扫字体。 - 命令集:`instances`、`install`、`launch`、`accounts`、`sessions`、`logs`、`diag`、`config`、 - `java`、`agent`,外加 `--help` / `--version`。 -- **另有一个更轻的 `ull`**(`cargo build --release --bin ull`,零 UI 依赖):同一套命令,但二进制不 - 链接任何图形栈——连 fontconfig 都不需要。服务器、CI 容器、Termux 拿 `ull`;有桌面的机器拿 - `unlucky-launcher`,一个文件同时管 GUI 与命令行。两者都从下一个 tag 起进发布资产 - (`v0.1.0` 的资产早于这个变化)。 -- Windows ARM64 与 Linux ARM64 两个槽位已接进发布流水线,随下一个 tag 发布;`v0.1.0` 的资产早于 - 这两个槽位。 - -### 轨道 B —— dev 上的下一代 UI(iced + M3 Expressive,施工中) - -**这条轨道还没发布——要看只能自己从源码编。** - -- **方向已锁死**:视觉 = Material 3 Expressive,框架 = iced 0.14,UI 层从头写;风格与框架都不会再换。 -- **已完成**:令牌 crate `crates/design`(零 UI 框架依赖、零第三方 crate——真 HCT 色彩、排版档位、 - 形状刻度、间距、高程、动效、图标几何、组件度量)与骨架 crate `crates/app-iced`(能开窗、自绘标题栏 - 与窗口键、导航轨、颜色与字号只从令牌取、GPU→CPU 后端探测与自动降级、视觉验收用的截图与逐像素 - 对比通道)。 -- **没完成**:组件库(按钮、对话框、列表、菜单、搜索栏,以及 M3 其余组件)、页面搬迁、i18n 文案。 - iced 版里现在每一个页面都是占位。 +- **iced 版界面功能已齐**:十四页——实例、版本管理(三栏 + 搜索)、内容库(整合包 / Mod / 资源包 / + 光影,带来源与版本筛选)、日志、设置(通用 / 外观 / Java / 下载)、账户(微软设备码、第三方社区服、 + 本地档案)、AI 右栏,以及安装流程——共用一套组件库与一套令牌。 +- **文案跟随系统语言**:自动探测、设置里可显式切换、重启后保持。界面文案统一走一份消息目录,视图层 + 没有硬编码字符串。 +- **外观**:窗口背景图、面板透明度、整窗透明度(Windows)、浅色 / 深色 / 跟随系统,以及在系统愿意给 + 的时候使用系统窗口圆角。CPU 渲染档会关掉半透明层,并在界面上说清楚。 +- **整合包与安装链路都在构建里**:CurseForge 清单 / Modrinth `.mrpack` / MultiMC·Prism 导入,mrpack + 与 CurseForge 导出,安装选项(选加载器)与**真取消**。 +- **还没做**:安装器与自动更新通道;Windows 定型后的 macOS 真机复核;整合包导入的**逐文件**冲突策略 + (当前只有一份全局策略,界面如实写明而不是假装支持);原生文件选择框(导入支持拖拽与粘贴路径)。 - **Slint 版已退出构建,只留源码作参考**:`crates/app` 不再是 workspace 成员(M118)——源码留作历史 - 参考,不编译、不测试、不发布,也不再有可用的构建方式。翻牌只剩**改名**这一步:在 iced 版通过等价 - 验收前,它的 bin 还叫 `unlucky-launcher-iced`;发布流水线已经把它按对外名 `unlucky-launcher` 打出去。 + 参考,不编译、不测试、不发布,也不再有可用的构建方式。翻牌只剩**改名**这一步:它的 bin 现在叫 + `unlucky-launcher-iced`,发布流水线已经把它按对外名 `unlucky-launcher` 打出去。 可能会遇到的 bin,先认清楚: @@ -115,8 +91,11 @@ unlucky-launcher --version # CLI,输出版本 + 系统摘要 Unlucky-Launcher (cargo workspace) ├── crates/core # 领域库:零 UI 依赖,八模块 ├── crates/agent # AI Agent:ToolSpec 注册表 + 内置客户端 + MCP server(双形态共用一个内核) +├── crates/presenter # 业务宿主层:与框架无关的 state / host / dto / 转换 ├── crates/design # 设计令牌:真 HCT 色彩 / 排版 / 形状 / 间距 / 高程 / 动效 / 图标 / 组件度量 │ # —— 零 UI 依赖、零第三方 crate +├── crates/i18n # 语言探测、消息目录、中文字体策略 +├── crates/palette-extract # 唯一解码图片的 crate,供壁纸取色链路使用 ├── crates/app # 历史 Slint UI(bin `unlucky-launcher`):已被 workspace `exclude`, │ # 仅作源码参考——不再被构建 / 测试 / 发布 ├── crates/app-iced # iced UI(bin `unlucky-launcher-iced`):workspace 里唯一的 GUI bin