Four repositories · one project

Nomad

An AI coding editor that runs on your own models and goes where you go. You work with an agent on a PC, and you can pick up the same session from a phone or iPad, at home or across the internet.

Dart + Flutter Windows · Linux · iPad · iPhone local or hosted LLMs end-to-end encrypted remote
The whole system

How the pieces fit

The PC is the host: it runs the agent, touches the files and calls the model. The phone is a remote control for that session. NomadCore is the engine both host apps are built on.

Phone or iPad connects to the host PC directly on the same Wi-Fi, or through NomadRelay across networks. The host runs NomadEditor or NomadCLI, both built on NomadCore, which talks to the LLM, the workspace, MCP tools and the web. REMOTE DEVICE Phone or iPad NomadEditor, connected to a session · send prompts · review edits, approve commands · watch it work, hit Stop SAME WI-FI · DIRECT LAN, port 9933 NomadRelay self-hosted, blind matches by Device ID, forwards opaque bytes DIFFERENT NETWORKS · BOTH SIDES DIAL OUT YOUR PC · THE HOST NomadEditor desktop app editor, chat panel, git, terminal FLUTTER or NomadCLI headless host chat in a terminal, no GUI needed PURE DART built on NomadCore the engine, shared by both hosts agent loop · built-in tools · git · shell LLM + MCP clients · SSH workspaces host side of the remote protocol LLM server llama.cpp, LM Studio, Ollama, any OpenAI-style API, or Claude Workspace a local folder, or a remote machine over SSH / SFTP MCP tools extra tools over HTTP, incl. a Playwright browser for the agent The web web fetch, and Brave Search for looking things up
end-to-end encrypted depends on / calls runs on one machine
The four repositories

What each one does

Move your pointer over a drawing to play with it.

ben/NomadEditor · Flutter app

NomadEditor

The app you see: a VS Code-style editor with an agent chat panel. Runs on desktop, and on phone or iPad as the remote control.

  • Code editorTabs, split view, syntax highlighting for ~40 languages, find in files, command palette.
  • Agent chatPlan and Implement modes, multiple conversations, @file mentions, slash commands, images for vision models.
  • You stay in chargeEdits wait for your review, down to single hunks. Shell commands need approval unless a rule allows them.
  • Git and terminalBranches, diffs, commit, pull, push, and a built-in terminal, locally or over SSH.
  • Fits any screenThree panes on desktop, a drawer on tablets, bottom tabs on phones.
ben/NomadCLI · command-line host

NomadCLI

The same agent without the GUI. cd into a project, run nomadcli, and chat in the terminal. Leave it running so a phone can connect.

  • Terminal chatType a message; approve commands and edits with y / a / n. Ctrl+C stops a turn.
  • Hosting/remote or --remote opens the session to phones on the LAN and through a relay.
  • One per projectEach folder gets its own Device ID and port, so several can run at once.
  • Setup commandsconfig, devices, status, init: set the model, relay, browser and paired devices.
ben/NomadCore · shared Dart package

NomadCore

The engine. Everything that does real work lives here, with no Flutter dependency, so the editor and the CLI behave the same.

  • Agent loopCalls the model, runs tools, pauses for your decisions, compacts long chats, keeps a to-do list and memory.
  • Built-in toolsRead, write, edit and search files; git; shell and background processes; diagnostics; web; sub-agents.
  • Model clientsAny OpenAI-compatible server, plus Anthropic's native API. MCP client for extra tools.
  • WorkspacesOne interface for files, git and shell, with local and SSH versions.
  • Project rules.nomad/project.json: allow/deny lists, check and format commands, hooks.
  • Remote hostDevice identity, pairing and encryption for the host side of a session.
ben/NomadRelay · small server, Docker

NomadRelay

An optional meeting point for when the phone and PC are on different networks, such as cellular. You host it yourself.

  • MatchmakerThe PC registers as a listener, the phone asks for that Device ID, and the relay joins them.
  • Blind forwardingTraffic is already encrypted end to end. The relay passes bytes along and can't read them.
  • No stateNo accounts, no database, no logs. A restart just makes both sides reconnect.
  • No port forwardingBoth sides make normal outbound WebSocket connections. Put a TLS proxy in front for wss://.
In motion

Two things that happen all the time

Connecting a phone

Modelled on RustDesk: devices trust each other, not an account.

  1. Every host has an identity. An Ed25519 key pair, shown as a Device ID.
  2. Pair once. The phone enters the host's address and a PIN (or scans a QR code). Next time it reconnects without one.
  3. Agree on a key. X25519 and HKDF give a session key, and every frame is sealed with AES-GCM.
  4. Pick a route. On the same Wi-Fi it connects directly. Otherwise both sides go through your NomadRelay.
  5. Mirror the session. The phone shows the chat, edit reviews, command approvals and the to-do list, and can press Stop.

One agent turn

What happens between your message and the answer, on the editor, the CLI or the phone.

  1. You ask. The message goes out with the project's AGENTS.md, the to-do list and any files you mentioned.
  2. The model picks tools. It reads and searches the code, runs git, opens a browser page, and so on.
  3. It pauses for you. Proposed edits show as a diff to accept in full, in part or not at all. Unlisted shell commands wait for Approve / Always allow / Deny.
  4. Checks run. Formatters run on changed files and the project's check command reports errors, which go back to the model to fix.
  5. Done. You get the answer and the changes, with undo or a one-click revert of the whole turn.