docs(readme): 状态段改成当前事实,模块地图补齐三个 crate
状态段原来停在「iced 版每个页面都是占位」——早就不成立了。改成: 十四页功能已齐、文案跟随系统语言、外观三件套、整合包导入导出与安装选项, 以及明确列出「还没做」的四项(安装器与自动更新、macOS 定型复核、 逐文件冲突策略、原生文件选择框)。 模块地图补上 crates/presenter、crates/i18n、crates/palette-extract, 并写明分层:app-iced → presenter → core/agent,design 与 i18n 不得反向依赖渲染框架。
This commit is contained in:
1 parent
4a212760b6
commit
1315b37f62
2 files changed
+76
-111
No files matched your search
@@ -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 <instance>`,
|
||||
`unlucky-launcher logs <sid>` 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 <command>` 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 <command>` 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
|
||||
|
||||
Reference in new issue
Block a user