Skip to content

Latest commit

 

History

689 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LeapMux

LeapMux

Docs Release Container License: FSL-1.1-ALv2 llms.txt

A terminal works fine for one or two coding agents side-by-side. At three or four — one refactoring, one on tests, one chasing a failing build — shell tabs stop helping: you lose track of which one owns which branch, the agents clobber each other's working tree, and a stray tmux crash or dev-box reboot means re-launching each agent with --resume and rebuilding the layout by hand.

LeapMux is a workspace for running several coding agents and shell terminals at once, each in a git worktree and branch you pick, tiled or floating, on a local or remote machine. Sessions stay attached across restarts, and Frontend↔Worker traffic is end-to-end encrypted. Runs in the browser or as a native desktop app.

Supported Agents

                 

📖 Want to use LeapMux?

Read the docs and grab a download at leapmux.dev. The rest of this README covers building and developing LeapMux from source.

Table of Contents

Architecture

LeapMux is a single Go binary (leapmux) plus a SolidJS frontend and a Tauri desktop shell, organized into three components:

  • Frontend — SolidJS web app that renders the workspace UI (tiling layout, agents, terminals, file browser); also embedded in the desktop app.
  • Hub — Go service for login, workspace management, and worker registration, and an authenticated relay for end-to-end-encrypted Frontend↔Worker traffic. Storage is pluggable: SQLite (default), PostgreSQL, MySQL, CockroachDB, YugabyteDB, or TiDB.
  • Worker — Go process that runs agents, PTYs, file browsing, and git operations; keeps its own SQLite and connects outbound to the Hub, so it can live behind a NAT.

The binary runs in several modes:

Command Description
leapmux solo Hub + Worker, single-user; local IPC needs no credential and TCP starts with password setup
leapmux hub Central service only (auth, relay, database)
leapmux worker Connects to a remote Hub
leapmux dev Hub + Worker on all interfaces, login required
leapmux control admin Online, authenticated CLI for users, workers, OAuth, settings, and tokens
leapmux recover Offline break-glass CLI: first-admin bootstrap, password reset, encryption keys, database

Frontend↔Hub uses ConnectRPC; Frontend↔Worker uses hybrid post-quantum Noise_NK multiplexed over a single Hub-relayed WebSocket; Worker↔Hub uses gRPC. The Hub routes traffic but can't read Frontend↔Worker content. The wire format is Protocol Buffers in /proto/leapmux/v1/; every constant shared across Go, TypeScript, and Rust is defined once in /contracts/ and generated into each language.

LeapMux supports exactly one active Hub process per database. The Hub holds a database-backed runtime lease and refuses to serve when another live Hub owns it; a replacement can take over after graceful release or lease expiry. Administrative CLI processes may still access the database while the Hub is running.

For the full architecture, deployment modes, and threat model, see the Concepts and Security & Threat Model chapters at leapmux.dev.

Prerequisites

The rest of this README is for people building LeapMux from source or hacking on it. To just run LeapMux, grab a desktop app or server build from the releases page, or read the docs at leapmux.dev.

Before you begin, ensure you have the following installed:

  • Go 1.27.1 or later
  • Node.js 24 or later
  • Bun 1.4.0 or later - JavaScript runtime and package manager
  • Task - Task runner (replaces Make)
  • buf CLI - Protocol Buffer code generation (authentication recommended to avoid rate-limit errors)
  • protobuf (protoc) - Protocol Buffer compiler (required by Tauri's prost-build)
  • SQLite (usually pre-installed on most systems)
  • Docker - Required for building Docker images (on macOS, Rancher Desktop is recommended)
  • mprocs - Multi-process runner (required for task dev, task dev-solo, and task dev-desktop)
  • Rust toolchain - For the Tauri desktop app (built by task build)
  • Tauri desktop prerequisites - WebView/system packages required by Tauri on your platform

Go-based build tools — sqlc, golangci-lint, and gotestsum — are declared as tool dependencies in backend/go.mod and invoked automatically via go tool <name>. You don't need to install them separately.

macOS

Install Bun by following the instructions at https://bun.sh/.

Install the remaining dependencies with Homebrew:

brew install buf go go-task mprocs node protobuf rust

For building Docker images, install Rancher Desktop (or any Docker-compatible runtime such as Docker Desktop or OrbStack) separately.

Arch Linux

Install the official repository packages with pacman:

sudo pacman -S buf bun go go-task nodejs npm protobuf rust

The Arch go-task package installs the binary as go-task. Add a shell alias so that task works:

# Add to your ~/.bashrc or ~/.zshrc
alias task=go-task

Install the remaining dependencies from the AUR (using yay or your preferred AUR helper):

yay -S mprocs-bin

For desktop app builds, install the Tauri prerequisites for Arch Linux plus GStreamer (bundled into the AppImage by bundleMediaFramework) and dpkg (its dpkg-deb builds the .deb bundle; not installed by default on Arch):

sudo pacman -S webkit2gtk-4.1 libayatana-appindicator librsvg patchelf dpkg \
  gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad-libs gst-libav

Windows

Install dependencies with winget:

winget install --id Microsoft.PowerShell --source winget
winget install --id GoLang.Go --source winget
winget install --id OpenJS.NodeJS.LTS --source winget  # or OpenJS.NodeJS for the current (non-LTS) release
winget install --id Oven-sh.Bun --source winget
winget install --id Task.Task --source winget
winget install --id bufbuild.buf --source winget
winget install --id pvolok.mprocs --source winget
winget install --id SUSE.RancherDesktop --source winget  # or any other Docker-compatible runtime (e.g. Docker.DockerDesktop, Podman.Podman)
winget install --id Rustlang.Rust.MSVC --source winget
winget install --id Google.Protobuf --source winget
winget install --id Microsoft.VisualStudio.BuildTools --source winget  # or Microsoft.VisualStudio.2022.Community if you prefer the full IDE

After Microsoft.VisualStudio.BuildTools installs, open the Visual Studio Installer and modify the installation to enable the "Desktop development with C++" workload — winget installs the bootstrapper but does not select any workloads automatically.

For the remaining Tauri Windows prerequisites (WebView2, etc.), see the Tauri Windows prerequisites.

Quick Start

Get LeapMux running locally:

# 1. Clone the repository
git clone https://github.com/leapmux/leapmux.git
cd leapmux

# 2. Generate code and download assets (protobuf, contracts, sqlc, and spinner JSON — not checked into git)
task generate

# 3. Start all services (requires mprocs)
task dev

Once all services are running, open your browser to:

http://localhost:4327

Each dev target generates code and builds prerequisites, then launches mprocs to run the processes concurrently:

Command Processes Description
task dev Go backend (leapmux dev) + Bun frontend dev server Full-featured dev mode on all interfaces, login required
task dev-solo Go backend (leapmux solo) + Bun frontend dev server Localhost-only, single-user; the browser sets the first solo password
task dev-desktop Bun frontend dev server + Tauri desktop app Desktop app development (builds sidecar first)

Development

Building

Build all components:

task build

Build individual components:

task build-backend    # Build leapmux binary (Go)
task build-frontend   # Build frontend assets
task build-desktop    # Build desktop app for current platform (Tauri v2 + Rust)

The leapmux binary is output to the repository root. Tauri emits the desktop bundles under desktop/rust/target/, and the final artifacts (.dmg on macOS, .AppImage/.deb on Linux, .msi/.exe on Windows) are also copied to the repository root.

Testing

Run all tests (except E2E):

task test

Run specific test suites:

task test-backend       # Backend tests
task test-frontend      # Frontend tests (Vitest)
task test-desktop       # Desktop Go sidecar + Tauri Rust shell tests
task test-e2e           # End-to-end tests (Playwright)

Run specific tests by passing arguments after --:

# Backend tests: -run <regex> <packages>
task test-backend -- -run TestMyFunction ./internal/hub/...

# Frontend unit tests: pass a file path to Vitest
task test-frontend -- src/lib/validate.test.ts

# E2E tests: pass a file path or --grep <pattern> to Playwright
task test-e2e -- tests/e2e/040-chat-message-rendering.spec.ts
task test-e2e -- --grep "should persist theme"

Linting

Run all linters:

task lint

Run specific linters:

task lint-versions   # Check documented tool versions against versions.env
task validate-json   # Validate every project-written JSON file against its schema
task lint-proto      # Lint Protocol Buffer definitions
task lint-backend    # Lint Go code (hub + worker)
task lint-frontend   # Lint frontend code (TypeScript typecheck + ESLint)
task lint-desktop    # Lint desktop Go sidecar (golangci-lint) + Tauri Rust shell (clippy)

Auto-fix lint violations:

task lint-fix            # Fix all (Go, frontend, desktop)
task lint-fix-backend    # Fix Go code (golangci-lint --fix)
task lint-fix-frontend   # Fix frontend code (ESLint --fix)
task lint-fix-desktop    # Fix desktop Go code + Tauri Rust code (clippy --fix)

Desktop Prerequisites

Desktop builds use Tauri v2:

  • macOS: Xcode Command Line Tools, Rust, WebKit (system)
  • Linux: Rust plus the WebKitGTK/Tauri native dependencies for your distro (see Tauri Linux prerequisites) and GStreamer (see the Arch Linux section above)
  • Windows: Rust MSVC toolchain plus WebView2

Code Generation

Regenerate all generated code and downloaded assets (Protocol Buffers, contracts, sqlc, and spinner JSON):

task generate

You can also run each generator individually:

task generate-proto      # Generate Protocol Buffer code (Go and TypeScript)
task generate-contracts  # Generate Go/TS/Rust constants from contracts/*.json (the single source for every cross-language value)
task generate-sqlc       # Generate type-safe SQL code (hub and worker)
task generate-spinners   # Download spinner verb JSON files from awesome-claude-spinners

Task uses checksums to skip generation when source files haven't changed. To force regeneration, use task --force generate.

Always run task generate-proto after modifying .proto files in /proto/leapmux/v1/. Always run task generate-sqlc after modifying .sql files in /backend/internal/hub/store/*/db/queries/ or /backend/internal/worker/db/queries/. Always run task generate-contracts after modifying contracts/*.json. Adding a proto enum value (AgentProvider, Scope) fails generation until its contract entry exists.

Preparation

Prepare every module for builds (code generation, frontend install, asset generation, icon generation, and embedding the frontend into the backend):

task prepare

You can also run each step individually:

task prepare-frontend   # Generate proto/contracts/spinners, run bun install, generate icons, copy NOTICE.html
task prepare-backend    # Generate proto/contracts/sqlc, build the frontend, and embed it into the backend
task prepare-desktop    # Generate proto/contracts, build the frontend, prepare the backend, and generate desktop icons

Note: Build targets automatically run their required preparation steps, so task build works without running task prepare first.

Third-Party License Notice

Generate NOTICE.md and NOTICE.html with all third-party dependency licenses:

task generate-notice

Run this manually after changing dependencies; regular build targets do not trigger it. The task fails if any dependency is missing a license file or if a vendored override's license identifier no longer matches the upstream package.

Cleaning

Remove all build artifacts and generated code:

task clean

Clean a specific module:

task clean-backend    # Remove leapmux binaries and generated/ directories
task clean-frontend   # Remove .output, .vinxi, node_modules, and generated/ directories
task clean-desktop    # Remove desktop binaries, bundles, the generated contracts module, and Rust target/

Docker images

Build Docker images containing the full LeapMux stack:

# Build both Alpine and Ubuntu images
task docker-build

# Build only Alpine
task docker-build-alpine

# Build only Ubuntu
task docker-build-ubuntu

By default this builds for linux/amd64 and linux/arm64. You can override the platform and tag:

task docker-build-alpine PLATFORM=linux/amd64 TAG=leapmux:dev

The image uses a multi-stage build (buf, Bun, Go). Tool and base image versions are centralized in versions.env at the repository root.

Tool versions

versions.env is the single source of truth for every toolchain and base-image version. Taskfile.yaml loads it via dotenv:, the CI workflows splat it into $GITHUB_ENV, and docker/Dockerfile takes it as build ARGs — those consumers read it directly and need nothing further.

Prose (this README, the docs site) and the go directive in each go.mod have nowhere to put a variable, so they are generated from it instead:

task sync-versions   # rewrite those copies from versions.env
task lint-versions   # fail if one has drifted (runs as part of task lint)

After editing versions.env, run task sync-versions. Adding a new place that states a version means adding a claim to CLAIMS in scripts/sync-versions.mjs; a claim whose pattern stops matching is a hard error, so a reworded line fails the build rather than silently going stale.

Documentation site

The site at leapmux.dev is a Hugo + Hextra project under site/. Hugo is declared as a go tool dependency (see site/go.mod), so there's nothing extra to install.

task site        # Build the static site into site/public/
task dev-site    # Live-reload dev server at http://localhost:1313

Technology Stack

Frontend

  • Bun - Runtime and package manager
  • ConnectRPC - RPC client for browser
  • Noble - Cryptographic primitives for E2EE (X25519, ML-KEM-1024, SLH-DSA, ChaCha20-Poly1305, BLAKE2b)
  • Lucide - Icon library
  • Milkdown - Markdown editor
  • Oat - Classless CSS framework
  • Playwright - End-to-end testing
  • Shiki - Syntax highlighting
  • Solid DnD - Drag-and-drop support
  • SolidJS - Reactive UI framework
  • SolidStart - Solid meta-framework (routing, build)
  • Vanilla Extract - Type-safe CSS-in-JS
  • Vinxi - Build framework (Vite-based)
  • Vitest - Unit testing
  • xterm.js - Terminal emulator

Hub (Central Service)

  • ConnectRPC - Modern gRPC-compatible RPC framework (Frontend communication)
  • Go - Primary language
  • Goose - Database migrations
  • gRPC - Standard gRPC (Worker communication)
  • koanf - Layered configuration (defaults, file, env)
  • Protocol Buffers - Service and message definitions
  • Pluggable database - SQLite, PostgreSQL, MySQL, CockroachDB, YugabyteDB, or TiDB (see Architecture)
  • sqlc - Type-safe SQL code generation (per-backend: SQLite, PostgreSQL, MySQL)

Worker (Agent Wrapper)

  • CIRCL - SLH-DSA post-quantum signatures for E2EE channel handling
  • Git - Repository info and worktree management
  • Go - Primary language
  • gRPC - Communication with Hub
  • SQLite - Embedded database for agent and terminal state

Desktop

  • Tauri v2 - Desktop application framework (Rust + native WebView)

Site (Documentation)

Build Tools

  • buf - Protocol Buffer tooling
  • ESLint - TypeScript/JavaScript linting
  • golangci-lint - Go linting
  • mprocs - Multi-process runner for development
  • Task - Build orchestration with checksum-based caching

Project Structure

leapmux/
├── backend/             # Go backend: the unified `leapmux` binary (hub + worker)
│   ├── cmd/leapmux/     # Entry point, subcommand routing, recover + control trees
│   └── internal/
│       ├── hub/         # Hub: auth, channel relay, pluggable store, keystore, OAuth
│       └── worker/      # Worker: agents, terminals, file browser, git, E2EE channel
│           └── agent/   # Agent runtime: the neutral API, and one package per provider in providers/
├── contracts/           # Cross-language constant contracts (JSON + sibling JSON Schema), generated into Go/TS/Rust
├── desktop/             # Tauri v2 desktop app (Rust shell + Go sidecar)
├── docker/              # Dockerfile and s6-overlay service definitions
├── frontend/            # SolidJS web app
│   └── src/components/  # UI: chat (+ per-agent renderers), terminal, files, shell
├── icons/               # App and agent-provider SVG icons
├── proto/leapmux/v1/    # Protocol Buffer service and message definitions
├── scripts/             # Build scripts: contracts/proto generation, JSON-schema validation, NOTICE, icons
├── site/                # Hugo + Hextra documentation site (leapmux.dev)
│   └── content/docs/    # The user manual
├── testdata/            # Cross-language conformance corpora (JSON + JSON Schema), replayed by the Go and TS suites
├── go.work              # Go workspace (backend + desktop/go)
├── Taskfile.yaml        # Build orchestration (go-task.dev)
└── versions.env         # Version string and tool/image versions

Contributing

We don't accept code contributions yet. The reason is licensing: LeapMux is under FSL-1.1-ALv2, which automatically converts to Apache 2.0 over time, and that relicensing is only possible if we hold the rights to every line of code. Without a Contributor License Agreement (CLA) in place, accepting outside contributions now would make that switch extremely hard — we'd have to track down every past contributor for their consent. Once a CLA is ready, we expect to open up to external contributions.

In the meantime, please feel free to create issues, preferably with a plan generated by a frontier model; we will follow them up.

License

LeapMux is licensed under the Functional Source License, Version 1.1, Apache 2.0 Future License (FSL-1.1-ALv2).

This means:

  • You can use, modify, and distribute the software
  • There are certain limitations on competitive use
  • The license automatically converts to Apache 2.0 two years after each release is first made available

See the LICENSE file for full details.

Disclaimer

All product names, logos, and trademarks are the property of their respective owners. LeapMux is not affiliated with, endorsed by, or sponsored by Anomaly, Anthropic, Anysphere, Apple, Block, Cognition, Don Ho, Earendil, GitHub, Google, JetBrains, Kilo Code, Microsoft, OpenAI, Sublime HQ, Z.ai, Zed Industries, or any other third party. Coding agent, editor, and IDE icons are used solely to indicate compatibility and are reproduced here for identification purposes only.