The agent loop is the easy part.
Juggler is a GUI-first AI coding harness, built by Julian Storer (JUCE, Tracktion, Cmajor). It's a native Go server, conversations are CRDTs synced live to local and remote clients, and no Electron in sight.
- Open source
- Free
- No account
- Vendor-neutral
- Direct to your provider
Under the hood
-
A native app and a matching server
The backend is Go; the interface is type-checked JavaScript served directly, with no frontend compilation step. Conversations are Yjs documents, so every connected client converges on the same live state.
-
A state machine, not a while-loop
The turn cycle — model, tools, approval, next call — advances by named state transitions in the conversation document, not by a loop holding it all in memory. An approval is a state rather than a blocked process, so a turn can be interrupted anywhere and carry on later as if nothing had happened.
Everything is an extension
Juggler is assembled from a small set of abstractions, and every one of them is a capability an extension can supply — even read, write and bash go through the public SDK. There is no privileged inner tier.
// A tool the model can call: a JSON schema in, an approval gate if
// it's destructive, a structured result out.
import ContextItem from 'juggler/context-item';
// The policy of the agentic loop: which tools exist this turn, what
// gets auto-approved, what guidance the model is given.
import Strategy from 'juggler/strategy-type';
// A slash command — no LLM, no approval, the simplest capability.
import Command from 'juggler/command-type';
// An environment for a conversation's tools to run in. The built-in
// git-worktree, scratch-copy and project-folder providers are three;
// an ssh host or a container could be a fourth.
import WorkspaceProvider from 'juggler/workspace-provider';
// Owns a file type end to end: how it renders for you, and what the
// model sees of it — two different jobs, in two different places.
import FileViewer from 'juggler/file-viewer';
// An ambient tile in the sidebar, alongside Tips and Git status.
import InfoCard from 'juggler/info-card-type';
// A view the user pins beside the conversation. Display only, by
// design: it has no way to feed the model.
import PinboardItem from 'juggler/pinboard-item-type';
Those imports are real. Writing an extension starts with a single scaffold command.
Your agent's conversation is a tree, not a log file.
Branch at any point: send a tangent, a delegated task or a competing approach into a sub-thread, and bring back only its result instead of pouring the whole excursion into your main context.
-
A desktop interface for long sessions
Using a coding agent means reading and editing substantial amounts of text. Juggler gives that work a proper interface: Miller-column navigation and focused views, built for long sessions.
-
Branching is recursive
A sub-thread can have sub-threads. Explore a tangent or a competing approach as deep as it needs to go.
-
Everything important is inspectable
Open tool arguments, approvals and results in their own views. Open any model transaction: system prompt, messages, tool definitions, output, token use, timing, stop reason.
Give each agent its own place to work
Run several conversations on one project without them treading on each other: each works in its own workspace — a git worktree on another branch, a throwaway scratch copy, or one folder of a monorepo.
Run it where the code lives
Launch the desktop app and everything runs locally. When the project lives on a dev box or server, run Juggler there instead: the session lives with the code, and every connected client — app, browser, phone — stays in sync.
The Context Surgeon
An agent's context should not be a sealed container. Open the assembled system prompt and tools, fold history into a new thread, move items between branches, expand a branch back into its parent — and undo any of it.
-
Sessions survive quits and reconnects
A session lives on disk, not just in memory. Quit, relaunch or lose the connection and the conversation is still there, including an agent waiting for you to approve its next step.
-
Vendor-neutral, with no house model
Claude Code, Anthropic, OpenAI, Codex, GitHub Copilot, Gemini, Mistral, Z.AI, Ollama, OpenRouter, DeepSeek and other OpenAI-compatible providers. Bring a subscription you already pay for, or your own API keys. Juggler sells no tokens, so it has no stake in which you pick — switch provider or model mid-conversation.
-
Nothing intercepts what you send
Model traffic goes direct from your machine to the provider you chose: no server in the path, no cloud index of your repository. Conversations and API keys stay on your own disk, and the source is public, so none of that has to be taken on trust.
-
Context limits are handled before they become your problem
Juggler sizes the complete request before each call, leaves room for the answer, and compacts older history when a conversation outgrows the model's window.
-
MCP tools, fully inspectable
Connect a local or remote MCP server and follow the whole handoff: schema, generated arguments, approval, result. Check server status and logs, filter individual tools, and see what a past model turn actually received.
-
AGPLv3 application, permissive extension SDK
The application is AGPLv3; the extension SDK and bundled extensions are Apache-2.0, so extensions can remain closed source. A build from source supports local and LAN access; the official binaries add WAN modes — see LICENSING.md for the boundary.
Who's building this?
I'm Julian Storer. I've been building tools for developers and musicians since the 1990s, and these days most of my own work happens through a coding agent. Juggler exists because I wanted that tool to be worth living in. And somehow I seem to have ended up writing it myself...
Active development
Frequent releases, shaped by people using it on real projects — the changelog has the details.
Constructive feedback is welcome on the Discord.
No terminal required
The desktop app
Download and launch it. The app starts its matching local server and opens your project.
For long-lived & remote sessions
The terminal server
Run the headless juggler binary where your code lives, then attach from a browser or the desktop app.
Free to download. Open source. No Juggler account. No Electron.