Skip to content

Architecture

Overview

┌──────────┐     ┌──────────────┐     ┌────────────┐
│ futo-cli  │────→│  futo-daemon  │←────│  futo-gui   │
│ (clap)    │     │  (long-lived)  │     │ (Tauri v2)  │
└──────────┘     └───────┬───────┘     └────────────┘
                         │  \\.\pipe\futou (JSON-RPC 2.0)
              ┌──────────┴──────────┐
              │     futo-core        │  domain + services + port traits
              │     futo-ipc         │  shared message types + catalogue
              └─────────────────────┘

Crate Map

futo-ipc — Shared Types

JSON-RPC 2.0 message types, catalogue data model, error codes. Zero logic. Consumed by every other crate.

futo-core — Domain Logic

Hexagonal ports-and-adapters design. Domain types (RuntimeName, Version, DaemonState), 7 port traits (Downloader, Extractor, ProcessManager, etc.), and 4 service orchestrators (InstallService, ActivationService, CatalogueService, EnvService). No I/O — pure logic.

futo-daemon — Background Process

Long-lived Windows service. Manages downloads via aria2c, extracts archives, persists state to state.json, exposes 14 JSON-RPC methods over a named pipe pool (4 concurrent instances). System tray icon for quick shutdown.

futo-cli — Terminal Frontend

clap-powered CLI with 8 subcommands. Connects to daemon via Windows named pipe, sends JSON-RPC, prints results. 30-second timeout on all pipe reads.

futo-gui — Desktop Frontend

React 19 + Tailwind v4 + Tauri v2. Thin Rust proxy layer that forwards Tauri IPC commands to the daemon's named pipe. Features frameless window, EN/ID localization, settings panel, document root prompt for web servers.

Data Flow

Install

CLI/GUI → runtime.install RPC → handler → InstallService
  → CatalogueSource.fetch_version_urls()
  → Downloader.download() (aria2c)
  → verify_checksum() (SHA256)
  → Extractor.extract()
  → RuntimeRepository.save() (state.json)

Activate

CLI/GUI → runtime.activate RPC → handler → ActivationService
  → ShimManager.create_shims() (.bat files)
  → PathManager.add_to_path() (Windows registry)
  → RuntimeRepository.save()

Start Server

CLI/GUI → runtime.start RPC → handler → ActivationService
  → ProcessManager.init_data_dir()
  → ProcessManager.start_server()
  → RuntimeRepository.save() (persist PID)

State

All state lives at %APPDATA%\.futou\:

FilePurpose
state.jsonInstalled runtimes, active versions, running PIDs
settings.jsonGUI settings (language, install location)
runtimes/Extracted runtime binaries
catalogue/Cached catalogue from remote URL
shims/.bat shim files for activated runtimes
aria2/aria2c downloads and PID file