Usine is a desktop app that orchestrates LLM coding agents (the claude and
codex CLIs) on a kanban board. Each card is a unit of work that moves through a
pipeline — design a plan, get it approved, implement it on a git worktree/branch,
open a pull request, address review comments, and merge — with the agents doing
the heavy lifting and you stepping in to answer questions and approve at the
gates.
You'll need the Rust toolchain — if you don't have cargo yet, install it via
rustup first. Usine is distributed as a Cargo package, so
a single command builds it from source and drops a usine binary into
~/.cargo/bin (which rustup already puts on your PATH):
cargo install --git https://github.com/sigma-studios/usine usine-app --lockedThat's all you need on macOS and Windows. On Linux, install a couple of system libraries first (the app uses your system's webview, and the git integration links libgit2/openssl):
# Debian / Ubuntu
sudo apt install libwebkit2gtk-4.1-dev libssl-dev pkg-configTo update later, run the same cargo install … command again.
usineRunning usine launches the app detached: the window opens, your terminal
prompt returns immediately, and the app keeps running even if you close the
terminal — on every platform. (Set USINE_NO_DETACH=1 to keep it in the
foreground and watch its logs instead.)
Demo mode runs the whole pipeline with simulated agents — no agents launched, no tokens spent, no network, and a separate database so it never touches your real board:
USINE_SIM=1 usineBy default Usine drives the real backends, so it expects these installed and
authenticated on your PATH:
- the
claudeCLI and/or thecodexCLI, depending on the provider you pick per card, git, andgh(the GitHub CLI) for the pull-request integration.
If you only want to explore the UI, use USINE_SIM=1 — none of the above are
needed.
Projects, cards, and history are stored in a local database under your platform's data directory:
- macOS:
~/Library/Application Support/dev.usine.usine/usine.db - Linux:
~/.local/share/usine/usine.db - Windows:
%APPDATA%\usine\usine\data\usine.db
Demo mode (USINE_SIM=1) uses a separate usine-demo.db in the same location.
Usine is a standard Cargo workspace (Rust, edition 2021) built with Dioxus. Clone it and work from the repo root:
git clone https://github.com/sigma-studios/usine
cd usineInstall the Dioxus CLI once, then use dx serve for a live-reloading dev loop —
edits to the UI and styles reload without a full restart:
cargo install dioxus-cli
dx serve --package usine-appDev builds (dx serve, cargo run) intentionally stay in the foreground so
hot-reload and live logs work — only the installed release binary detaches
itself.
cargo build --workspace # build everything
cargo test --workspace # test everything
cargo run -p usine-app # run the app (real backends)
USINE_SIM=1 cargo run -p usine-app # run in demo mode (simulated backends)The usine-cli crate is a headless harness that drives the same core through
the executor, used for smoke tests and live integration tests:
cargo run -p usine-cli # simulated end-to-end pipeline
cargo run -p usine-cli github # live GitHub forge test (throwaway repo)
cargo run -p usine-cli real-e2e # full real run through the executor
cargo run -p usine-cli real-plan <dir> <task...> # one real `claude` plan over <dir>
cargo run -p usine-cli mcp # relay stdio to a running app's MCP socketThe MCP server is on by default; cargo build --workspace --no-default-features
leaves it out entirely (see below).
USINE_DATA_DIR=<path> relocates the whole data directory — database,
worktrees, and attachments — letting a second instance run fully isolated from
the main one. An absolute path is recommended; it composes with USINE_SIM (the
demo DB name applies under whichever directory is active).
Usine serves a small MCP surface over the board, so an external agent — a terminal Claude Code session, say — can see what's in flight and file new work without you switching apps. Six tools:
| Tool | |
|---|---|
list_projects, list_cards, get_card, get_plan |
read the board |
create_project, create_card |
add a repo / file a card in the starting block |
Nothing here can start an agent run: a card created over MCP lands in the starting block and waits for you. It does appear on an open board immediately — the write goes through the same executor command the UI uses.
Register it with a client:
cargo build -p usine-cli
claude mcp add usine -- "$PWD/target/debug/usine-cli" mcpThe server runs inside the desktop app (redb allows a single writer, so no
separate process can open the database while Usine is running), and listens on a
Unix socket at <data_dir>/mcp.sock, mode 0600 — mcp-demo.sock under
USINE_SIM=1. A USINE_DATA_DIR instance therefore gets its own socket exactly
as it gets its own database, and usine-cli mcp reaches whichever one its own
environment points at. The app must be running; a socket left behind by a crash
is replaced on the next launch, and a live one is never stolen.
It is behind the mcp cargo feature, on by default in all three crates.
--no-default-features compiles the module — and tokio's net stack — out, and
no socket is created.
When a project's setup/teardown commands are left blank, Usine auto-detects
setup-worktree.sh / teardown-worktree.sh (also under scripts/) in the
worktree and runs them. Anything these scripts write inside the worktree must be
gitignored — agent runs commit with git add -A.
Usine can manage its own repository as a project. Add the repo as a project, set
a validate command (e.g. cargo test --workspace), and set the run command to:
USINE_DATA_DIR="$PWD/.preview-data" cargo run -p usine-appEach preview then launches a fully isolated instance whose state lives inside the card's worktree and is disposed of with it. Two things to know:
.preview-data/must stay gitignored (it is, in this repo) — otherwise the preview instance's database would be committed by the agent's finalize step.- If you launch a second instance without
USINE_DATA_DIR, it finds the main instance's database locked and falls back to an in-memory store (an error toast tells you); nothing is corrupted, but nothing persists either.
Merged changes don't reach the running app — rebuild and relaunch to pick them up.
The workspace is split into three crates:
usine-core(libusine_core) — UI-agnostic domain logic. It owns the domain model, the pure card state machine, typed persistence (vianative_db), git and forge (GitHub viagh) integration, the provider abstraction, and the async executor that ties them together. It has no UI dependencies.src/mcpis a self-contained, feature-gated MCP server over the board.usine-app(binusine) — the Dioxus desktop UI. A thin, reactive view overusine-core: it sendsCardCommands to the executor and renders theExecutorEvents it drains back.usine-cli(binusine-cli) — a headless harness that drives the same core through the executor.
Provider factory (Phase A vs Phase B). A ProviderFactory is injected into
the executor; the executor logic is identical regardless of which it gets. Phase
A injects simulators (SimFactory / SimForge / SimGit) so the whole pipeline
runs with no agents, tokens, or network. Phase B injects the real backends
(RealFactory / GhForge / RealGit), which shell out to the real
claude/codex CLIs, git, and gh.
Threading. The executor runs on its own background thread with a dedicated
multi-threaded Tokio runtime, communicating with the UI entirely over channels
(an unbounded CardCommand channel in, an unbounded ExecutorEvent channel
back). This keeps the executor's async work off the UI's single-threaded Dioxus
runtime, which simply drains events in one place. The MCP server, when
compiled in, gets a third thread and its own current-thread runtime — the app
starts it, so nothing a client does can wedge the runtime driving agent runs.
MIT — see LICENSE.