Developer guide
Build nui from source, understand the architecture, and contribute.
Prerequisites
- Go 1.26+
- Node.js 18+
- Agent CLIs on
PATHas needed:claude,pi,codex,opencode - Docker (optional) — for
sandbox: docker, custom docker-harness ADL agents, and devcontainer harnesses - Dev Container CLI (optional) — for
harness.type: devcontainer(npm install -g @devcontainers/cli)
Project structure
nui/
├── main.go, embed.go # entrypoint; embeds ui/dist
├── cmd/ # cobra CLI (nui server, extension, skills, …)
├── internal/
│ ├── model/ # Session, ChatMessage, ADL structs
│ ├── agent/ # Agent interface, harness implementations, ADL executor
│ ├── server/ # HTTP mux, REST + AG-UI streaming
│ ├── store/ # JSON persistence (~/.nui/)
│ └── extensions/ # Extension registry, install, RPC
├── docker/ # Builtin sandbox images (HTTP/SSE, port 8090)
├── harness-sdk/ # Python extension author SDK
├── sdk/ # Programmatic extension SDKs (Python, TS, Go)
├── dev/ # Specs, examples, extension-api.md
└── ui/ # Vite + React frontend
Running in development
Terminal 1 — Vite dev server (proxies /api to Go):
cd ui && npm install && npm run dev
Terminal 2 — Go server (ui/dist must exist before go build):
cd ui && npm run build && cd ..
go run . server # default :8080
go run . server --port 3000 # custom port
Production build:
cd ui && npm run build && cd .. && go build -o nui_bin . && ./nui_bin server
Architecture
flowchart TB
subgraph ui [Browser]
Chat[ChatPanel / useSessionChat]
end
subgraph server [Go server :8080]
API[REST API]
AGUI["/api/sessions/:id/ag-ui"]
ADL[ADLAgent]
Mgr[Manager]
end
subgraph builtins [Builtin harnesses — Go subprocess]
CC[ClaudeCodeAgent]
PI[PiAgent]
CX[CodexAgent]
OC[OpenCodeAgent]
end
subgraph connectors [Connectors — HTTP/SSE]
HTTP[HTTPExtensionAgent]
Docker[(Docker container)]
Remote[(Remote server)]
end
Chat -->|AG-UI SSE| AGUI
AGUI --> ADL
ADL --> Mgr
Mgr --> CC & PI & CX & OC
Mgr --> HTTP
HTTP --> Docker & Remote
Session flow: every session has an agentType that resolves to an ADL definition (built-in or ~/.nui/agents/*.yaml). ADLAgent runs the harness — single-step for simple agents, multi-step DAG for workflows. The UI streams chat over the AG-UI protocol at POST /api/sessions/:id/ag-ui. The home launcher uses POST /api/orchestrate with the built-in nui master agent.
REST API (selected)
| Endpoint | Description |
|---|---|
GET/POST /api/sessions |
List / create sessions |
POST /api/sessions/ensure-default |
Return last session or create with default agent |
GET/PATCH/DELETE /api/sessions/:id |
Get / rename / delete |
GET/PUT /api/sessions/:id/messages |
Persisted UI messages |
POST /api/sessions/:id/ag-ui |
Primary chat endpoint (AG-UI protocol) |
POST /api/orchestrate |
Home-launcher orchestration (nui master agent) |
GET /api/orchestrator/routable-agents |
Agents eligible for launcher delegation |
GET /api/agent-types |
Builtin + user + extension ADL types |
GET/PUT /api/settings |
User preferences |
GET /api/extensions |
Installed extensions and contribution ids |
POST /api/extensions/reload |
Rescan ~/.nui/extensions/ |
GET /api/memory |
Memory summary |
GET/PUT /api/mcp-servers |
User MCP server config |
POST/GET/DELETE /api/mcp-oauth/* |
Remote MCP OAuth flows |
GET /api/hitl-channels |
HITL delivery channels |
POST /api/hitl/requests |
Create HITL request |
GET /api/capabilities |
bwrap availability |
Full tables live in DEVELOPERS.md and dev/dev.md on main. See Extension REST API for extension-specific endpoints.
Persistence
| File | Contents |
|---|---|
~/.nui/data.json |
Sessions, agent session ids, UI chat text |
~/.nui/settings.json |
Theme, default agent, sidebar state |
~/.nui/agents/*.yaml |
User ADL definitions |
~/.nui/extensions/<name>/ |
Installed extensions |
~/.nui/connections/*.json |
TCP/HTTP harness handshake files |
~/.nui/harness-sdk/ |
Auto-installed Python SDK modules |
Testing
Run the full suite locally:
./scripts/test-all.sh
CI runs Go tests, harness-sdk pytest, UI lint/build/Vitest, Playwright E2E, and a binary size check on every PR.
Individual commands:
go test . ./cmd/... ./internal/...
pytest harness-sdk
cd ui && npm run lint && npm run build && npm test
Contributing
- Fork and branch from
main - Run
./scripts/test-all.shbefore opening a PR - Keep extension examples generic — no org-specific config in tests
Releasing
- Bump
VERSIONonmain(currently0.4.0-alpha) - Tag:
git tag v0.4.0-alpha && git push origin v0.4.0-alpha - Create a GitHub Release — the workflow builds Linux and macOS binaries