Build from source
Building midna yourself is for working on it. To just use midna, download the DMG.
Requirements
Section titled “Requirements”- A Mac with Apple Silicon
- Xcode or the Command Line Tools
- Rust (edition 2024)
gitandcurl
The terminal engine (libghostty-vt) builds only with Zig 0.15.2 and a pinned ghostty source. A setup script fetches both.
git clone https://github.com/mrgnhnt96/midna.gitcd midna./scripts/setup-toolchain.sh. ./env.sh && cargo buildsetup-toolchain.shdownloads Zig 0.15.2 and the pinned ghostty source into.toolchain/. If your default macOS SDK is newer than Zig 0.15.2 can link against, it points it at an installed macOS 15 SDK instead. Running it again keeps what’s already there.- Always source
env.shbefore building. It puts the toolchain on yourPATHand sets the build options the engine needs.
cargo build produces three binaries in target/debug/: midnad (the daemon), midna (the CLI) and midna-app (the GUI).
cargo test --workspace # every test uses a temporary MIDNA_HOMEscripts/smoke.sh # end-to-end check against a real temporary daemonRun in dev mode
Section titled “Run in dev mode”Use a temporary home with a short path. Unix socket paths are limited to 104 bytes, and you don’t want to touch your real midna data.
export MIDNA_HOME=$(mktemp -d /tmp/mh.XXXX)MIDNA_APP_PATH=$PWD/target/debug/midna-app target/debug/midnad --foreground &target/debug/midna-app # the GUItarget/debug/midna info # the CLItarget/debug/midna open -- /bin/zsh # prints the new terminal's idMIDNA_BACKEND=fake target/debug/midna-app # the GUI with sample data, no daemonMIDNA_APP_PATH tells a debug daemon which binary counts as the human; release builds ignore it. A dev build of the app registers nothing and never updates. If no daemon is answering, it starts the midnad next to it.
Package a Midna.app
Section titled “Package a Midna.app”packaging/build-app.sh # -> dist/<version>/Midna.appThe app is signed with the first Developer ID Application certificate in your keychain, or ad hoc if there isn’t one. An ad-hoc build is a new app to macOS each time, so permissions like Accessibility don’t carry over between builds. It also falls back to recognizing the app by name, which is weaker than the signature check signed builds get.
A build you make yourself doesn’t carry midna’s release update key, so it won’t install updates from the official feed.
Layout
Section titled “Layout”| Crate | What it is |
|---|---|
midna-proto |
Shared types, the method catalog and OpenRPC, the settings catalog |
midnad |
The daemon: terminals, policy, triggers and webhooks, insights, in-place upgrade |
midna-cli |
The midna command, midna mcp, and the agent hook bridge |
midna-app |
The GPUI app: Midna.app |
The design notes are in docs/: ARCHITECTURE.md for the contract, DECISIONS.md for the reasoning, and SECURITY.md for the human/agent boundary.