Skip to main content
The OpenFang Desktop App is a native desktop wrapper built with Tauri 2.0 that packages the entire OpenFang Agent OS into a single, installable application. Get a native window with system tray integration, OS notifications, and single-instance enforcement.
Crate: openfang-desktopIdentifier: ai.openfang.desktopProduct name: OpenFang

Architecture

The desktop app follows an embedded-server pattern:

Startup Sequence

1

Tracing Init

tracing_subscriber is configured with RUST_LOG env, defaulting to openfang=info,tauri=info.
2

Kernel Boot

OpenFangKernel::boot(None) loads the default configuration from config.toml, wrapped in Arc. Calls set_self_handle() for self-referencing kernel operations.
3

Port Binding

A TcpListener binds to 127.0.0.1:0, letting the OS assign a random free port. This ensures the port is known before creating the window.
4

Server Thread

Dedicated OS thread named "openfang-server" spawns with its own tokio::runtime. Runs:
  • kernel.start_background_agents() - heartbeat monitor, autonomous agents
  • run_embedded_server() - axum router via build_router(), serves with graceful shutdown
5

Tauri App

Tauri builder assembles with plugins, managed state, IPC commands, system tray, and WebView window pointing at http://127.0.0.1:{port}.
6

Event Loop

Tauri runs its native event loop. On exit, server_handle.shutdown() stops the embedded server and kernel.

Graceful Shutdown

The axum server uses with_graceful_shutdown() wired to a watch channel:
After shutdown, channel bridges (Telegram, Slack, etc.) are stopped via bridge.stop().await.

Features

System Tray

The system tray provides quick access without bringing up the main window:
Left-click on tray icon shows the main window (same as “Show Window” menu item).

Single-Instance Enforcement

On desktop platforms, tauri-plugin-single-instance prevents multiple copies from running simultaneously. When a second instance attempts to launch, the existing instance’s main window is shown, unminimized, and focused.

Hide-to-Tray on Close

Closing the window does not quit the application. The window is hidden and the close event is suppressed:
To actually quit, use the “Quit OpenFang” option in the system tray menu.

Native OS Notifications

The app subscribes to the kernel’s event bus and forwards critical events as native desktop notifications: All other events are silently skipped.

IPC Commands

Eleven Tauri IPC commands are registered, callable from the WebView frontend via invoke():

Core Commands

get_port

Returns the port number (u16) the embedded server is listening on.

get_status

Returns runtime status:

get_agent_count

Returns the number of registered agents (usize).

import_agent_toml

Opens native file picker for .toml files. Validates as AgentManifest, copies to ~/.openfang/agents/{name}/agent.toml, and spawns the agent.

Skill & Config Commands

import_skill_file

Opens file picker for skill files (.md, .toml, .py, .js, .wasm). Copies to ~/.openfang/skills/ and triggers hot-reload.

open_config_dir

Opens ~/.openfang/ in the OS file manager.

open_logs_dir

Opens ~/.openfang/logs/ in the OS file manager.

Auto-Start Commands

get_autostart

Check if OpenFang launches at OS login.

set_autostart

Toggle auto-start. Uses tauri-plugin-autostart (launchd on macOS, registry on Windows, systemd on Linux).

Update Commands

check_for_updates

Checks for available updates without installing:

install_update

Downloads and installs the latest update, then restarts the app. Does not return on success (app restarts).

Window Configuration

The main window is created programmatically: The window uses WebviewUrl::External(...) because the WebView renders the axum-served UI.

Auto-Updater

The app checks for updates 10 seconds after startup. If available, it downloads, installs, and restarts automatically. Flow:
  1. Startup check (10s delay) → check_for_update() → if available → notify user → download_and_install_update() → app restarts
  2. Tray “Check for Updates” → same flow, with failure notification if install fails
Configuration (in tauri.conf.json):
  • plugins.updater.pubkey — Ed25519 public key (must match signing private key)
  • plugins.updater.endpoints — URL to latest.json (hosted on GitHub Releases)
  • plugins.updater.windows.installMode"passive" (install without full UI)
Signing: Every release bundle is signed with TAURI_SIGNING_PRIVATE_KEY (GitHub Secret). The tauri-action generates latest.json with download URLs and signatures. See the Production Guide for key generation and setup instructions.

Content Security Policy

The tauri.conf.json configures a CSP that allows connections to the local embedded server:
This permits the WebView to load content from the localhost API server while blocking external resource loading.

Building

Prerequisites

  • Rust (stable toolchain)
  • Tauri CLI v2: cargo install tauri-cli --version "^2"
  • Platform-specific dependencies:
    • Windows: WebView2 (included in Windows 10/11), Visual Studio Build Tools
    • macOS: Xcode Command Line Tools
    • Linux: libwebkit2gtk-4.1-dev, libappindicator3-dev, librsvg2-dev, libssl-dev, build-essential

Development

Launches the app with hot-reload support. Console window is visible in debug builds.

Production Build

Produces platform-specific installers:
  • Windows: .msi and .exe (NSIS) installers
  • macOS: .dmg and .app bundle
  • Linux: .deb, .rpm, and .AppImage
The release binary suppresses the console window on Windows via:

Plugins

| Plugin | Version | Purpose | |--------|---------|---------|| | tauri-plugin-notification | 2 | Native OS notifications for kernel events and update progress | | tauri-plugin-shell | 2 | Shell/process access from the WebView | | tauri-plugin-dialog | 2 | Native file picker for agent/skill import | | tauri-plugin-single-instance | 2 | Prevents multiple instances (desktop only) | | tauri-plugin-autostart | 2 | Launch at OS login (desktop only) | | tauri-plugin-updater | 2 | Signed auto-updates from GitHub Releases (desktop only) | | tauri-plugin-global-shortcut | 2 | Keyboard shortcuts (desktop only) |

Capabilities

The default capability set grants:
Only the "main" window receives these permissions.

Mobile Ready

The codebase includes conditional compilation for mobile platform support:
  • Entry point: The run() function is annotated with #[cfg_attr(mobile, tauri::mobile_entry_point)]
  • Desktop-only features: System tray, single-instance, and hide-to-tray are gated behind #[cfg(desktop)]
  • Mobile targets: iOS and Android builds are structurally supported by Tauri 2.0

Next Steps

Production

Deploy OpenFang in production environments

CLI Reference

Full CLI command documentation