Skip to content

Rust rewrite: multi-account agent, QEMU launcher and web GUI - #1

Merged
itouakirai merged 4 commits into
litefrom
refactor/rust
Oct 11, 2026
Merged

itouakirai merged 4 commits into
litefrom
refactor/rust

Conversation

@itouakirai

@itouakirai itouakirai commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

Merges wrapper-manager's multi-account features into wrapper-lite and replaces every host-side component (C launchers, C++ QEMU launcher, Go GUI) with one Rust binary, wrapper, plus a new web panel. lite (C++, links Apple's Android libraries) keeps its role and HTTP API; it only gains --code-timeout.

Delivered in four commits:

  1. Agent (crates/agent): one supervised lite process per account (readiness via /status, health checks, exponential backoff, FairPlay circuit breaker), two-phase 2FA login through 2fa.txt (credentials passed via LITE_ARGS_FILE, not argv), region-aware routing with catalog/lyrics probes and retries, wrapper-manager compatible /status /login /logout, /api management API with optional bearer token and SSE, wrapper sandbox-exec (userns chroot) replacing wrapper-lite.c / wrapper-lite-rootless.c, migration of the legacy single-account layout.
  2. QEMU (crates/host): wrapper qemu replaces wrapper-lite-qemu; the guest init runs wrapper agent, formats a blank data disk on first boot (no data.img shipped), passes args via fw_cfg, shuts down cleanly through the API. wrapper login / wrapper accounts CLI.
  3. GUI: Svelte 5 + Vite panel in web/, embedded by build.rs; wrapper with no subcommand opens it. Dashboard, accounts with 2FA dialog, logs, settings, package download, API tester; light/dark, zh/en, mobile layout.
  4. Build/cleanup: new CI, thin Android shell (WebView + foreground service running libwrapper.so), Docker on the native agent, old launchers and Go GUI removed.

Design notes: docs/ARCHITECTURE.md.

Breaking changes

  • Artifacts are renamed to wrapper-<os>-<arch> (wrapper-android-apk for the APK); old nightly links stop working.
  • The old GUI and wrapper-lite, wrapper-lite-rootless, wrapper-lite-qemu binaries are gone. An existing data.img / rootfs/data is migrated to the first account.
  • A guest/rootfs built before this PR does not understand the new agent's --code-timeout; the agent reports this as a version mismatch.

Testing

Done locally:

  • cargo test (28 tests, incl. HTTP tests against fake lite upstreams) and cargo clippy --all-targets clean on Windows and Linux.
  • Real lite in a chroot (WSL1, direct runtime): login failure reason from Apple surfaces correctly; supervisor lifecycle (migration, backoff, stop/start, graceful exit).
  • Real QEMU on Windows (WHPX): boot, disk formatting and persistence, fw_cfg args, graceful shutdown; GUI engine control, agent/public proxies, no orphaned QEMU after the GUI is killed; panel screenshots (desktop and mobile).

Verified by CI (run 38126123368, all jobs green):

  • Rootless sandbox runs a freshly built lite; native agent starts and /status answers (guest job)
  • Android aarch64-linux-android binary and APK build
  • Windows, macOS, Linux x86_64/aarch64 packages build

Still to verify by hand:

  • Docker image (not built in CI)
  • The APK on a device
  • Successful login with a real account, 2FA, and /key /m3u8 through multi-account routing

🤖 Generated with Claude Code

WorldObservationLog and others added 4 commits October 11, 2026 15:43
Introduce a Cargo workspace with the `wrapper` binary and the
`wrapper-agent` library, merging wrapper-manager's multi-account
features into wrapper-lite:

- one supervised lite process per account (startup gating, /status
  readiness, health checks, exponential backoff, FairPlay circuit breaker)
- two-phase 2FA login via 2fa.txt; credentials passed through
  LITE_ARGS_FILE instead of argv
- region-aware routing with catalog/lyrics probes and retry policy
- wrapper-lite compatible resource API, aggregated /status,
  wrapper-manager compatible /login and /logout, /api management API
  with optional bearer token and SSE events
- `wrapper sandbox-exec`: user/mount/PID namespace chroot helper that
  replaces wrapper-lite.c and wrapper-lite-rootless.c
- migration of a legacy single-account /data layout

lite: add --code-timeout so the 2FA wait is configurable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- crates/host: QEMU lookup (explicit > QEMU_BIN > bundled > PATH),
  per-host acceleration (KVM/WHPX/HVF/TCG) with TCG fallback when the
  accelerator fails at boot, bundled firmware/library paths, fw_cfg agent
  arguments with a kernel-cmdline fallback, graceful shutdown through the
  agent API
- `wrapper qemu` replaces wrapper-lite-qemu; `wrapper login` and
  `wrapper accounts` manage a running agent from the terminal
- guest init runs `wrapper agent`, sets up DNS, formats a blank data disk
  on first boot (no data.img is shipped any more) and powers off cleanly
- agent: POST /api/system/shutdown, NO_COLOR support, and drain lite
  output after a login exits so the failure reason is not lost
- qemu/build.sh embeds the static musl wrapper and handles busybox in
  /usr/bin

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- web/: new Svelte 5 + Vite panel (dashboard, accounts with two-phase
  2FA login dialog, logs with source/level filters, settings, components
  and package download, API tester), light/dark themes, zh/en, mobile layout
- crates/host gui server: embeds web/dist via build.rs, persistent
  settings with a generated management token, engine controller for the
  QEMU and native engines, console buffer and SSE events, platform
  package download with zip-slip protection that keeps user data,
  /api/agent and /api/public proxies, optional access token for
  non-loopback listening
- `wrapper` without a subcommand opens the panel; children are killed
  with the GUI (job object on Windows) and closing the console stops
  the engine gracefully
- agent: explain "unknown argument" login failures as a lite/wrapper
  version mismatch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CI: Rust checks on Linux and Windows, web panel build, lite (NDK),
  QEMU guest with a rootless-sandbox and native-agent smoke test,
  wrapper-<os>-<arch> packages (QEMU bundled; linux-x86_64 also ships
  the rootfs for the native engine), Android binary + APK
- Android: Kotlin reduced to a WebView plus a foreground service that
  runs the bundled libwrapper.so (`wrapper gui`) with wake/Wi-Fi locks
- Docker: builds lite and wrapper and runs the native agent
- remove wrapper-lite.c, wrapper-lite-rootless.c, wrapper-lite-qemu.cpp,
  the Go GUI and its duplicated web assets, unused cmdline.c/h,
  entrypoint.sh and qemu/mkdata.sh; CMake now only builds lite
- agent creates the Android app data dir on boot
- GUI installs downloaded packages next to the assets dir (writable on
  Android)
- .gitattributes forces LF for shell scripts and the guest init
- README rewritten for the multi-account workflow

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@itouakirai
itouakirai merged commit 31ce4a2 into lite Oct 11, 2026
10 checks passed
@itouakirai
itouakirai deleted the refactor/rust branch October 11, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants