AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
midna는 AI 에이전트와 작업하기 위한 macOS 전용 터미널입니다
midna is a native macOS terminal for working with AI agents. Agents can open and read terminals through a CLI and MCP server, approvals from every terminal land in one queue, and your shells keep runn
개발 도구Rust · ShellGitHub @mrgnhnt96온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
A macOS terminal built for working with AI agents
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
midna is a macOS terminal built for working with AI agents. It replaces Saggar.
• Projects group terminals, which run shells, monitors, or agents (Claude Code, Codex).
• A daemon (midnad) is the source of truth. It owns every PTY, the terminal engines (libghostty-vt), projects, rules, triggers, settings, and the event and audit log. Closing or upgrading the GUI never kills a shell.
• Everything is AI-managed. Agents drive midna through the midna CLI, JSON-RPC over a Unix socket, or MCP. Every capability is a method in one discoverable catalog (midna schema).README 전문 보기 ↗midna is a macOS terminal built for working with AI agents. It replaces Saggar.
midnad) is the source of truth. It owns every PTY, the terminal engines (libghostty-vt), projects, rules, triggers, settings, and the event and audit log. Closing or upgrading the GUI never kills a shell.midna CLI, JSON-RPC over a Unix socket, or MCP. Every capability is a method in one discoverable catalog (midna schema).midna-app, GPUI).The design contract is docs/ARCHITECTURE.md. The reasoning behind it is in docs/DECISIONS.md. The security model and its limits are in docs/SECURITY.md.
Requirements:
.toolchain/ (Zig 0.15.2, an SDK shim, the ghostty source). It's gitignored; scripts/setup-toolchain.sh sets it up.Always source env.sh first.
. ./env.sh
cargo build # midnad, midna (CLI), midna-app
scripts/test.sh # every test, each on a temp MIDNA_HOME (one run at a time per Mac)
scripts/test.sh -p midna-app # or just the crates you touched (see AGENTS.md)
scripts/smoke.sh # end-to-end day in the life against a real temp daemon
Use a temp home with a short path, because Unix socket paths are limited to 104 bytes. Never use your real home.
export MIDNA_HOME=$(mktemp -d /tmp/mh.XXXX)
MIDNA_APP_PATH=$PWD/target/debug/midna-app target/debug/midnad --foreground & # GUI = human (debug builds only)
target/debug/midna-app # the GUI
target/debug/midna info # the CLI (an agent unless it's the GUI)
target/debug/midna open -- /bin/zsh # prints the new terminal id
MIDNA_BACKEND=fake target/debug/midna-app # GUI with sample data, no daemon
Useful dev environment variables:
| Variable | Effect |
|---|---|
MIDNA_SECRETS=file | File secrets instead of the Keychain |
MIDNA_WEBHOOKS_PORT=0 | Webhook receiver on any free port |
MIDNA_AGENT_BIN=/bin/echo | Stub instead of claude / codex |
MIDNA_NO_GH=1 | No gh lookups |
The MIDNA_DEBUG_* UI drivers work in debug builds only. See docs/STATUS-*.md.
packaging/build-app.sh # -> dist/<version>/Midna.app, Developer ID signed if a cert is present
scripts/reinstall.sh [--test] [--no-build] # rebuild the app and restart it; terminals survive
scripts/dev-app.sh [--test] [--no-build] # "Midna Dev" beside your real Midna: own home, daemon, CLI link; never updates
packaging/make-update.sh --app dist/<v>/Midna.app --url-base … # signed update feed
packaging/notarize.sh dist/<v>/Midna.app # opt-in, uploads to Apple
packaging/e2e/update-e2e.sh # full install + auto-update test (test bundle id, temp home)
What happens on first launch of the packaged app:
midnad into MIDNA_HOME/bin/<version>.~/.local/bin.Updates are verified with sha256, an ed25519 signature, codesign, and the Team ID. The daemon upgrades in place (same pid), and shells survive. Full details are in docs/RELEASING.md.
Inside a midna terminal, MIDNA_SESSION, MIDNA_PROJECT and MIDNA_SOCKET are set and midna is on PATH.
midna capabilities # what you can do, and what only the human can do
midna skill # the agent guide (also $MIDNA_SKILL)
midna info # your role and terminal
midna open --name tests --monitor 'cargo test' # a terminal the human can watch
midna send <id> 'ls' ; midna read <id> # drive and read another terminal
midna attention "need a decision on X" # get the human's eye
midna rules add deny command 'git push --force*' # agents may add rules…
midna rules request-removal <rule-id> --reason … # …but only ask to remove them
midna triggers add --name "Review PRs" --event pull_request.opened --repo me/repo \
--agent claude --project <p_id> --prompt 'Review PR #{{pr.number}}: {{pr.title}}'
midna explain <id|method|setting> # why something is the way it is
midna schema [method] # the OpenRPC catalog; `midna call <method> '<json>'` calls anything
MCP: midna mcp is a stdio MCP server that exposes every method as a tool. Agents that midna launches get it automatically (claude --mcp-config …, codex -c mcp_servers.midna…), along with hooks and a short system hint. midna never touches your global agent config.
Exit codes: 0 ok, 1 refused or failed, 2 bad arguments, 3 daemon unreachable.
Refusals say what to do next. A human-only call from an agent returns error 2 and raises a needs-you item instead.
crates/
midna-proto/ types, method catalog + OpenRPC, settings catalog, frame codec, blocking client
midnad/ the daemon (lib + bin): PTYs, engines, policy, triggers/webhooks, insights, upgrade
midna-cli/ `midna`: CLI verbs, `midna mcp`, `midna hook claude|codex`
midna-app/ the GPUI app (Midna.app): sidebar, terminal pane, ⌘K, needs-you, Rules,
Triggers, Insights, Settings, Kass composer, install + auto-update
docs/
ARCHITECTURE.md the build contract DECISIONS.md why things are the way they are
SECURITY.md human/agent boundary RELEASING.md build, sign, publish, install
STATUS-*.md per-area status (foundation, app, agents, triggers, upgrade, packaging)
design/ approved screen boards screens/ screenshots
packaging/ build-app.sh, make-update.sh, notarize.sh, gen-update-key.sh, e2e/, release-tool/
scripts/ smoke.sh, release.sh, set-version.sh, setup-toolchain.sh, build-dmg.sh
site/ midna.mrgnhnt.com: landing page, docs, changelog, download (Astro + Starlight)
spikes/ proven prototypes the crates grew from
Working and tested (details in docs/STATUS-*.md):
policy.request approvals, needs-you, settings, insights, header and row scripts, and git/PR info.docs/SECURITY.md).Known gaps:
docs/SECURITY.md).approval_policy="never".gh recovery against GitHub.RequiresApproval login-item flow.self_relay, midna_relay) aren't built.trigger.replay for agents.These need you (credentials, your screen, or your accounts). Nothing in this list was done automatically.
tb release cut v<version> (it runs scripts/release.sh); CI signs, notarizes and publishes them (docs/RELEASING.md). The release update key lives in ~/.config/midna-release and the repo's MIDNA_UPDATE_KEY secret.packaging/notarize.sh dist/<v>/Midna.app needs a notarytool keychain profile.docs/STATUS-app.md ("Kass composer"):
kass-probe … kass-sim 2.role=AXTextArea … Inserted{exact:true}.~/.codex/config.toml sets approval_policy="never". Use a temp CODEX_HOME with on-request (or a webhook-started Codex, which now runs on-request), and check that the prompt patterns and approve/deny from midna work.midna webhooks configure tailscale_funnel from the GUI (human only), and point a GitHub webhook at the public URL that midna webhooks status shows.triggers.agent_mode. The default is supervised, which forces permission prompts on webhook-started agents even though your global Claude config bypasses them. Switch to inherit only if you accept that risk. Local triggers (schedules, hooks) use your normal config; to give one trigger's agents their own mode or tools, use midna triggers update <id> --permission-mode auto --allow-tool <tool>.docs/SECURITY.md → "TCC responsibility". Agents in midna terminals may inherit that grant.