crates/, src-tauri/) and a React + TypeScript frontend (src/). You need both toolchains to run it.
Prerequisites
On Linux (Ubuntu 22.04, as in CI) the system packages are:
rustup target add wasm32-wasip2— building plugins and the plugin SDK (plugins/build.sh).cargo install cargo-nextest— the test runner CI uses (cargo testalso works).- The language servers, debuggers and toolchains of a language, for its smoke tests.
java/ are checked in as jars and embedded at build time.
Clone and run
1
Clone
sh git clone https://github.com/l0ng-ai/openidea.git cd openidea 2
Install frontend dependencies
sh pnpm install This also installs the pre-commit hook (simple-git-hooks + lint-staged), which runs
oxlint --fix, oxfmt and rustfmt on staged files.3
Run the app
sh pnpm tauri dev The first run is a full debug build of the workspace and takes several minutes. Later runs
are incremental; frontend changes reload through Vite without a rebuild.pnpm dev:app is the same as pnpm tauri dev, plus the global Tauri API (window.__TAURI__, from src-tauri/tauri.dev.conf.json), which is useful when you drive the app from scripts.
Other everyday commands:
Worktrees
Several worktrees can be developed and run side by side. Create one per task:pnpm tauri dev / pnpm dev:app, not the raw pnpm exec tauri dev. The wrapper (scripts/tauri.ts):
- starts Vite on a port derived from the worktree path (moving on if it is taken) and passes the actual URL to Tauri;
- refuses to start a second launcher for the same worktree and prints the running session instead;
- gives each worktree’s debug build its own app identity (
ai.l0ng.openidea.dev.w<hash>), so data, settings, logs and the single-instance lock are separate per worktree. Different worktrees and an installed release can run at the same time.
--release uses the normal release identity and bypasses the wrapper.
When you are done with a worktree: stop its app and dev session, delete its build output (target/), then git worktree remove ../my-task.
MCP bridge and ports
Debug builds load the Tauri MCP bridge plugin (tauri-plugin-mcp-bridge, bound to 127.0.0.1), which lets tools and agents drive the running app. Release builds don’t include it.
Bridge ports are dynamic, in the range 9223–9322. To find the one for your worktree:
port, appIdentifier). Connect to that port and pass appIdentifier explicitly; don’t assume the default MCP session belongs to your worktree. If no bridge is found, the app is still compiling or not running.
Common pitfalls
- Running a subset of frontend tests: use
pnpm vitest run <path>.pnpm test -- <path>ignores the filter and runs the whole suite, which takes several minutes. - Clippy while iterating: don’t.
pnpm tauri devcompiles anyway. Runcargo fmt --allandcargo clippy -p <crate> --all-targets -- -D warningsonce, before committing. A passing clippy doesn’t make the first launch faster:pnpm tauri devstill does a full debug build. - Long checks in one shell call: a cold build cache takes around 5 minutes. Run long checks one at a time rather than chained.
src/bindings.tschanges on launch: every debug launch re-exports the bindings (only rewriting the file when it differs). If you changed IPC types, commit the regenerated file; CI fails when it is stale.- Stopping processes: stop only what you started for your worktree. Never use broad kills such as
pkill openidea; they hit other worktrees and the installed app. - Raw Tauri CLI:
pnpm exec tauri devskips the worktree isolation above, so it can collide with another worktree’s Vite port or app identity.