# How OpenHuman's CLI Architecture Handles ServiceSet Resolution and HostKind Detection

> Discover how OpenHuman's CLI architecture resolves ServiceSets and detects HostKinds. Learn about its runtime initialization for Desktop, TUI, and Standalone environments.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: architecture
- Published: 2026-08-29

---

**OpenHuman's CLI orchestrates runtime initialization through two distinct phases: HostKind detection in [`src/core/host/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/host/mod.rs) to determine the execution environment (Desktop, TUI, or Standalone), followed by ServiceSet resolution in [`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs) to configure which background services (RPC, WebSocket, cron) should start based on detected host type and explicit CLI flags.**

The command-line interface in the `tinyhumansai/openhuman` repository serves as the central orchestration point for the entire system. Located in [`src/core/cli.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/cli.rs), the CLI initialization flow determines the runtime personality of the application through environment detection and service configuration. Understanding this **CLI architecture** is essential for deploying OpenHuman across diverse environments from desktop applications to headless servers.

## HostKind Detection Strategy

The first initialization phase identifies the execution context through the `HostKind` enum.

### Environment Detection Logic

In [`src/core/host/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/host/mod.rs), the `HostKind::detect()` method performs runtime inspection to classify the environment. This function evaluates three specific conditions to determine the appropriate host variant.

### Runtime Inspection Criteria

The detection algorithm checks for:

- **Tauri Runtime**: Presence of `window.__TAURI__` indicates a desktop webview context
- **TTY Availability**: Standard input being a TTY signals terminal UI (TUI) mode  
- **Standalone Fallback**: Absence of the above conditions defaults to `HostKind::Standalone` for headless server operation

The resulting `HostKind` variant (`Desktop`, `Tui`, or `Standalone`) propagates through the builder pattern to influence logging initialization and UI defaults.

## ServiceSet Resolution Mechanism

After host detection, the CLI determines which background services to instantiate through the `ServiceSet` type.

### CLI Flag Parsing

Located in [`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs), the `ServiceSet` struct consumes arguments parsed by `clap`. Explicit flags such as `--rpc`, `--socket`, `--cron`, and `--channels` map directly to service activation via `ServiceSet::from_cli(&args)`.

### Context-Aware Defaults

When no explicit service flags are provided, the system applies sensible defaults based on the previously detected `HostKind`:

- **Desktop**: Enables `rpc_http`, `socketio`, cron scheduler, and channel integrations
- **Standalone**: Restricts to `rpc_http` only for API server operation  
- **TUI**: Initializes with no background services, as the terminal interface drives core functionality directly

## Core Builder Integration

The resolved components assemble through `CoreBuilder` in a sequential flow:

```rust
// src/core/cli.rs ─ entry point
fn main() -> Result<()> {
    // 1️⃣ Parse command‑line arguments (clap)
    let args = Cli::parse();

    // 2️⃣ Detect the host environment
    let host = HostKind::detect(); // src/core/host/mod.rs

    // 3️⃣ Resolve which services to run
    let services = ServiceSet::from_cli(&args); // src/core/runtime/builder.rs

    // 4️⃣ Assemble the core runtime
    let core = CoreBuilder::new(host)
        .services(services)
        .domains(DomainSet::full())               // all domain families
        .build()
        .await?;

    // 5️⃣ Dispatch the chosen sub‑command (run, serve, etc.)
    core.run_subcommand(args.subcommand)
}

```

This architecture ensures that **HostKind detection** tailors logging (file-only for TUI versus Tauri window initialization) while **ServiceSet resolution** centralizes service lifecycle decisions.

## Deployment Patterns and Examples

The unified binary adapts to multiple deployment scenarios without recompilation.

**Desktop Application (Default Services)**

```bash
$ openhuman                # no flags → Desktop host detection

# HostKind = Desktop, ServiceSet = { rpc_http, socketio, cron, channels, ... }

```

**Headless API Server**

```bash
$ openhuman serve --rpc   # explicit service selection

# HostKind = Standalone, ServiceSet = { rpc_http }

```

**Terminal UI Mode**

```bash
$ openhuman tui            # forces HostKind::Tui

# HostKind = Tui, ServiceSet = {} (no background services; UI drives the core)

```

**Custom Service Composition**

```bash
$ openhuman serve --rpc --cron --no-channels

# HostKind = Standalone

# ServiceSet = { rpc_http, cron }   // channels deliberately omitted

```

## Summary

- **HostKind detection** in [`src/core/host/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/host/mod.rs) determines the runtime environment by inspecting Tauri presence and TTY status, returning `Desktop`, `Tui`, or `Standalone` variants.
- **ServiceSet resolution** in [`src/core/runtime/builder.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/runtime/builder.rs) translates CLI flags (`--rpc`, `--socket`, etc.) into service configurations, applying HostKind-specific defaults when flags are omitted.
- The `CoreBuilder` pattern in [`src/core/cli.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/cli.rs) chains these components with `DomainSet::full()` to produce a tailored runtime.
- This architecture enables a single binary to function as a desktop app, headless server, or TUI without recompilation.

## Frequently Asked Questions

### How does OpenHuman detect whether to run in desktop or server mode?

The system calls `HostKind::detect()` from [`src/core/host/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/host/mod.rs), which checks for the Tauri runtime environment and TTY availability. If it detects `window.__TAURI__`, it selects `HostKind::Desktop`; if standard input is a TTY, it selects `HostKind::Tui`; otherwise it falls back to `HostKind::Standalone` for server operation.

### What happens if I don't specify any service flags when starting OpenHuman?

When no explicit flags like `--rpc` or `--socket` are provided, `ServiceSet::from_cli()` applies default service groups based on the detected `HostKind`. Desktop hosts automatically enable HTTP RPC, WebSocket, cron, and channels, while Standalone hosts enable only HTTP RPC, and TUI mode starts no background services.

### Can I mix explicit service flags with default HostKind behavior?

Yes. The CLI architecture allows you to override specific services while maintaining the HostKind context. For example, running `openhuman serve --rpc --cron --no-channels` forces a Standalone host while explicitly enabling only RPC and cron services, excluding channels regardless of default settings.

### Where is the entry point for the CLI logic?

The main entry point resides in [`src/core/cli.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/cli.rs), which coordinates the initialization sequence: parsing arguments with `clap`, detecting the host environment, resolving the service set, building the core runtime via `CoreBuilder`, and dispatching subcommands.