Building Nagano
Running seven coding-agent CLIs from one approval queue
Nagano includes no model. A local daemon starts each agent’s own CLI as a supervised process and records every approval it asks for. How that works, and which agents ask.


Nagano is a macOS app for coding-agent CLIs. The window is a client of a local daemon on 127.0.0.1:7788, a Node process bundled inside the app. The daemon contains no harness implementation of its own. Each harness is a plugin: a separate process that speaks versioned JSON-RPC over NDJSON on stdio, selected through the nagano.plugins.json lock file and probed at startup. One session gets one process.
Seven harnesses, three protocols
Nagano talks to each CLI over that CLI's own interface. Claude Code streams JSON. Codex speaks its app-server JSON-RPC protocol. Kimi Code is run with --output-format stream-json. GLM is z.ai's Coding Plan, which runs the Claude Code binary against api.z.ai. Grok Build (grok agent stdio) and OpenCode Go (opencode acp) both speak ACP. Antigravity is Google's agy --print.
You install each CLI yourself; Nagano bundles none of them. Each one signs in on its own, and Nagano forwards no key unless you configure one. Health is a probe, not a version check: an ACP initialize handshake for Grok Build and OpenCode Go, the --help flags the plugin passes for Claude Code and Antigravity, a protocol compatibility probe for Kimi Code, the app-server's own init for Codex. Each verdict is cached by the binary's SHA-256, successes only, so a CLI that updates itself is re-verified automatically.
What an interaction is
When a harness asks for approval, asks a question or proposes a plan, the daemon records an interaction. GET /v1/interactions?state=pending is the inbox; POST /v1/interactions/{id}/resolve answers one, with a revision check so a stale answer is rejected. In the app that inbox is "Needs you" on the Dashboard, plus a notification, and each approval opens in the conversation that raised it.
The README lists the rules the daemon holds itself to. Every approval must offer deny or cancel, and any default in the interface must deny or cancel. Approval choices carry explicit scopes, and the execution envelope forbids persistent grants, so "always allow" cannot be expressed. The journal stores the option you chose and the plugin's acknowledgement separately, and presents neither as proof that the side effect happened. A plugin must supersede its unresolved interactions before it can end the turn. An interrupt that arrives first cancels pending approvals. After a daemon restart, a pending interaction becomes uncertain rather than being resolved for you.

Which agents ask
Each plugin declares what it can do in nagano-plugin.json. Five declare interaction.request.approval: Claude Code, Codex, GLM, Grok Build and OpenCode Go. Codex goes further and tells command approvals apart from file-change approvals. Claude Code and GLM also expose session.setPermissionMode, which is how a project's permission mode (ask, full or plan) reaches the CLI.
Kimi Code and Antigravity declare no interaction capability. They run non-interactively, so there is nothing to approve mid-turn: you get the result when the turn ends. That is a property of those CLIs today, not a setting in Nagano.
The rest of the window
The conversation view streams the transcript with tool calls, file events and a checkpoint timeline. Its side panel has Context (a token breakdown), Git (the diffstat), Preview and Ongoing. There is no code editor.
A project is a folder. One live session holds one directory at a time, enforced by a workspace lease in SQLite; a second job on a directory that another session owns gets 409 conflict before it is persisted. Git worktrees are how you run parallel lanes on one repository, and the New task sheet offers Same checkout, New worktree, and New worktree carrying your changes.
Orchestrate takes a brief and splits it into lanes across harnesses, in waves, with a plan card and lanes you can stop. The same thing exists on the command line: nagano orchestrate --plugin claude,kimi --start --wait.
Limits worth knowing
- macOS 15 or later, Apple silicon only.
- The journal at
~/.nagano/nagano.sqlitestores prompts, tool output and anything a harness prints, unredacted. The README calls the current security level a trusted local MVP. - The daemon listens on your LAN for pairing with other Macs and the iPhone app, gated by a QR code. Nagano runs locally, with optional pairing over your network; it is not "nothing leaves your Mac". Prompts and repository content go to each provider through that provider's own CLI.
- Titles, attention judgements and previews are produced by hidden jobs on your own harness, and they spend your quota.
- No analytics or crash reporting was found in the source.



