Repository navigation
feat(king): King Leon, a coordinator agent for every project - #61
Merged
Merged
Conversation
TurnSpec gains mcp_servers and instructions. Claude Code is told them with --mcp-config and --append-system-prompt, Codex in the thread's config and developerInstructions, and the Agent Client Protocol's agents in the session's mcpServers. Nothing sets them yet: the coordinator will.
leon-king holds what can be decided about King Leon without touching a disk: king.toml, the state of King's conversation and its workers and the effects each change asks for, the wake with news of the workers, the router that picks an agent by tier, usage and budget, the short transcripts, King's instructions and the control socket's messages.
leon king serve keeps King's conversation and its workers without a window: it runs their turns on pipes, saves its state after every change, wakes King with its workers' news and listens on a control socket only the user may open. King's agent runs in <data dir>/king with instructions listing every project, and is given leon king mcp (status, projects, usage, workers, diffs, pull requests, notifications) beside the shared memory and the board. Workers get a worktree of their own, never the default branch; pull requests are pushed without force and never merged. leon king say|status|log|start|tell|answer|stop|release| brain talk to it, starting the service when nothing answers. See docs/KING.md.
A new event, Usage, says what a turn read and wrote so far: Claude Code's result usage, the usage of an Agent Client Protocol prompt's answer, and what Codex's thread added since the turn began. The phone and the window do not show it yet; the coordinator reads it.
…nder every answer King is told every model the agents of this computer offer, asked the way the window's conversations ask, with what is known of each: talents from 1 to 5 and benchmarks with their sources. A built-in catalogue holds Leon's starting estimate and no benchmark; king-models.toml in the data folder, which King writes with model_note, wins over it. A plan job always runs on the planning tier (Opus at high effort, then Codex at high effort by default) and cheaper models are refused for it. Every turn is measured from the agents' own counts: tokens read, cached and written, tokens per second, cost. Under each answer of King's Leon writes that, what was spent and used today, and what is left of each agent's usage windows, and King reads the same before every turn.
… a file Leon's defaults for King are defaults.toml, commented key by key, and the person's king.toml is read over it key by key: a table named changes only the keys written, a tier named replaces that tier alone, and [] removes one. Where each kind of job goes is [jobs] (plans: the planning tier, strict), and the branches nothing is pushed to are [guards]. King's instructions list the jobs' rules from the configuration. leon king config prints the configuration in force, --defaults the defaults.
King Leon is a row of the sidebar's navigation and a view of the main pane (Ctrl+Shift+Alt+K): King's conversation with its field on the left, the workers it runs as cards on the right. A card opens the worker's conversation live, where the person can write to it, stop its turn, stop it or take it over; a worker taken over opens as a session of the window that continues its agent's conversation. Workers are never in the sidebar while they are King's. The window is one more client of King's service: a link opens the control socket (starting the service when nothing answers), asks for the status and for the entries it lacks, and is told of every change. Tests play the service through a fake link. The status now carries how each question may be answered, Leon's news to King is a transcript entry of its own, and notices say whether the conversation shows them already, so the window does not say them twice.
Alt and an answer's number answer the question in view (the open worker's, else King's), and each button says its key. The chip under King's field, or the palette's "Change the model King runs on…", asks for the agent, one of the models the service found, and the effort, and moves King there. The window tells the service while King's view is open in the window in front, and while anybody looks, what the conversation shows already is not also sent to the desktop.
* How much King asks is a chip beside its model: the permission modes its agent lists, kept like the model (`[brain] mode`). * "The King" sits above The Den; its answers get more line height and room, and the report under each is a strip: the turn's numbers, the day's, and a bar per usage window. The report's facts now travel with its entry. * King puts tasks on the board of the project it names (`task mcp --anywhere`, a `project` argument), and a card is given to King with `a` or from its details. * NEW puts King's conversation away; HISTORY lists the past ones, to read and to take up again (`leon king new`, `history`, `resume`).
* King runs in its agent's auto mode by default, and workers edit in their own worktree without asking (codex `auto`, claude `acceptEdits`): every question cost one of King's turns to answer. `""` is the agent's own mode. * What a worker asks is framed in King's view with its answers, without opening the worker; Alt and a number answer it. * King always names the model as well as the agent, and is told where to read the model a worker's agent chose by itself.
An image pasted into King's field is kept as a file in King's folder and its path written, for King and its workers to open; on Linux, where the toolkit sees no images, it is read with wl-paste or xclip. The paperclip attaches files as their paths, and dictation writes into King's field (or an open worker's) with the conversations' microphone and speech model.
…r result * A permission's choices are named by what they do (`d.2 = deny`), and King answers with allow, always or deny: a guessed Codex id denied what was meant to be allowed, and a denial ends a Codex turn. * A worker whose turn was stopped (a denial, an interrupt) waits, paused, instead of being marked failed. * A turn is over once the agent said its result, even while its process runs on for a program it left behind (a dev server); RUNNING lists those programs, with STOP. A turn in flight shows a spinner and its time. * Pasted images and attached files are chips over the field, sent as paths with the words.
…versations go on fresh * Leon answers a worker's routine permission itself, without waking King: an edit in its own worktree, a command that only reads, and tests, builds and servers run in the worktree. A push, a write out of the worktree, or a command it cannot read for sure still goes to King. The rules are `[permissions]`. * A turn of King's that read `compact_at_tokens` or more (600k) puts the conversation in the history; King goes on in a new one, told where it left off. * The field's key is part of its button: SEND ⏎, STOP ESC.
…its CI A worker saying it is done is not evidence. `worktree_check` runs the project's own check (scripts/check.sh, make check, cargo test, the package's check or test script, go test, pytest, or `[checks]` in king.toml) in the worker's worktree on its last commit, on a thread of the service's; King hears how it ended as news, with the end of what it printed, and the whole log stays in king/checks/<worker>.log. `pr_open` now needs a passed check of the branch's last commit (`[guards] verify_before_pr`), or a reason it cannot be checked, and writes the evidence in the description. On a branch whose pull request is open it pushes to it. The service then watches the pull request's CI with `gh` every `ci_poll_secs`, without King's turns, and wakes King when it settles: which checks failed, or that it passed, which also tells the person it is theirs to review. Each worker's card shows its check and its CI, and opens the pull request on a click. Also fixes what CI found on this branch: `king::Paths::new` used the Unix-only keeper on Windows, and the take-over test ended while the thread typing the agent's line still wrote to the terminal (macOS).
… reads are routine A request to read or resume a past conversation named it `id`, the envelope's own field once flattened: the service read the envelope's number instead, and refused. It is `conversation` now, with a test that every request survives the round trip. Each worker keeps the conversation that started it. WORKERS shows those of the conversation on screen, a past one's while it is read, and the earlier ones' that still work or ask apart; a conversation that goes on in a new one takes its workers along. Workers saved before are given the conversation that ran when they started. Leon also answers a worker's question about an MCP server's tool when the tool's name only reads (`[permissions] mcp_reading`); a name with a word of `mcp_writes` (create, delete, send, pay, generate…) still goes to King.
viktorvillalobos
force-pushed
the
feature/coordinator/init
branch
from
October 19, 2026 10:54
4971026 to
be9f7db
Compare
…ays why it passes over them
opencode 2.0.32 lists every provider's models in its answer to session/new and sends no config_option_update after it. A turn that asked for a model waited for that update forever and never sent its prompt: every opencode worker of King's hung on its first turn.
A task can be a step of another (its parent) and need other steps done first; the store refuses needs across boards and in a circle. A run of a task starts each step once what it needs is done and checked, at most run_parallel at once: in a worktree whose branch starts from what it needs, with a worker from its tier. When the worker finishes, Leon commits what it left and runs the project's check; a failed check goes back to the worker run_fixes times. King hears only when the run is done or blocked, and goes on with run_continue or calls it off with run_cancel. Started from the board (r, or Run its steps in the drawer, which lists the steps and how the run goes), from King (run_start) or from `leon king run`. Steps' tasks move across the board as they go.
Every answer drew its report with a bar for each usage window, so two answers in a row stacked two tall boxes. An older report is now its line of numbers, and one of a turn that used no tokens is left out.
leon king service install | uninstall | status | logs is leon host service for King: a systemd user unit or a launchd agent of its own that runs leon --data-dir <dir> king serve with the installing session's PATH, so King and its workers go on with the window closed and come back after a failure.
The wire gains King and KingClosed: lines of King's control protocol that the host passes through, both ways, to King's service on that computer, one connection per session opened by its first line. The host reads none of them and says it offers them after the Den in its ShareState answer. Both the window's host and leon host have the door, which starts the service when nothing answers, as leon king does. leon-link carries the lines (king_send, king_events) and leon-mobile offers king_ask, one request and its reply, and king_watch, King's notices, subscribing again after the line closed.
The phone reads King of the computer it paired with: its conversation, a field to say something, its workers and runs, and the notices King sends, followed while the screen is open. The computer's screen shows a King row when its host says it can. The bindings are generated again for king_ask and king_watch.
…e Den open_terminal asks the window to run a command in a session of its own, where the person sees its output: a dev server, a watcher. The service keeps the request until a window takes it, and only the first that asks gets it. Each worker that is still King's is a lion of the Den, as King's status says it stands and, while it works, as its transcript says; opening it opens its card. The window joins King's service whenever it runs, without starting it, so both follow King with its view closed.
TerminalTaken named its terminal id, which the envelope flattens over and reads as its own number, so no window could take one. It is terminal now, and the envelope test covers both new requests. The window also says, in its log, when it is on the line to King's service and why a terminal was not its to open.
Every worker leaves an outcome: each run of its check and whether it passed, its pull request's CI, a failed turn, what it cost and took. They are summed per agent, model and kind of job into a record kept with King's state. King reads it in models_list, and a tier passes over a model that keeps doing poorly at a kind of job while another candidate has room (learn_after, learn_below), saying so under passed_over.
A project on another machine gets its workers there: the worktree is made there, the agent runs there through the window's Reach, and the check, the diff, the pull request and the project's status run there. King's tools ask the service to run git and gh on another machine's folder; worker_start and open_terminal take the machine of an existing folder.
King can name an agent of Leon's catalogue it cannot drive on a pipe (Kimi, ZCode, Antigravity...): its worktree is made as for any worker and a window opens the agent there, on its prompt when the catalogue says how it takes one, else with the prompt shown above it. Leon runs no turn of it, so it cannot be told more, and its cost is recorded as not known rather than free.
The palette that picks King's model says, beside each model, what its record says per kind of job. A terminal worker's test gives the test computer Kimi instead of every test.
A conversation's foot says what the last turn read and wrote and how fast, as the agent counts it. The phone's turns now carry the same count.
The King screens answer the questions King and its workers wait on, tell a worker more, interrupt or stop it, and start, go on with or cancel runs. A worker on another machine or in a terminal says so.
The bindings carry the turn's Usage, and the chat shows the last turn's tokens and speed under its last answer, as the window does.
Leon's memory tools do not run on the other machine, so its worker is given the global notes and its project's with its instructions, and says what is worth keeping for King to keep.
A phone that asks gives King's service its Expo push token. When King tells the person something and no client shows King, the title and body are sent to Expo's push service; a phone Expo says is gone is forgotten.
A setting, off until turned on, gives each paired computer with King this phone's Expo push token, and takes it back when turned off; a computer that is offline is told when it next connects. Tapping such a notice opens King.
agy --help: --prompt-interactive runs an initial prompt interactively and continues the session. King's terminal workers on Antigravity now start on their task instead of waiting for the person to type it.
King's service waits for the commands of a worker on another computer. When the paired computer was off, each git command waited for it to connect (15 seconds) and a start took a minute, holding every other client of the service up. A computer the connection already found away now fails at once with why, and an answer that never comes is not waited for past the command's limit.
A line typed from a thread of its own woke the window's tasks from outside gpui's test scheduler, which failed King's terminal tests now and then under load (the gate of 486171c). The tests' readiness never looks, and a readiness that never looks types the line at once.
King's service is Unix's: on Windows what serves it is not used, and clippy refused it. On macOS the temporary folder is reached through a link, and `pwd` says the folder itself.
A new line or a lone & started another command that was judged as the first one's words; 1> was not a redirection; sed -Ei, --in-place and a script that writes or runs read as reading; a bare cd or cd - kept the worktree; git branch -D and -f, git -c and git diff --output read as reading; and a camelCase tool of an MCP server (sendMessage) hid its words. All of these now go to King.
…taken from another goal A task server that is not King's refused nothing when a call named another project's board. King's names it by its root without the separators at its end. task_create of a step whose title an open task already has re-parented that task; a task that is another's step, or waits for others, is now left alone and the call says so.
…kout, and the longest line A worker's folder is told apart by git: in a project's main checkout, the checkout or a folder of it, it is refused, and a worktree anywhere finds its project. King's worktrees follow worktree_location. A line as long as the wire allows is read: the new line that ends it is not counted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
King Leon: a principal engineer for every project
King is one agent that answers for every project Leon knows. You talk to it the way you would talk to a principal engineer: how something works, what state a project is in, what to build next, or to build it. Short questions it answers itself; long investigations and code changes go to workers, other agents (Claude Code, Codex, opencode, Grok, Cursor) on the cheapest model that can do the job, each in a worktree of its own. King commits, pushes and opens pull requests. It never merges, never pushes to a default branch and never forces a push; the tools refuse it, not only the prompt.
Full description:
docs/KING.md.What is in it
leon-king(new crate, pure): the coordinator as a state machine (King's conversation, its workers, the wake that gives King its workers' news so it never polls), the router (tiers, job rules, usage windows, daily budget), the transcript, King's instructions, the control protocol, the model catalogue (talents, benchmarks with source and date) and the report under every answer.leon king serve): runs headless, without the window, on a private Unix socket (same-uid peer check). The window, the command line and King's own MCP tools are its clients. State and past conversations survive restarts.leon king mcp): projects, usage, models, workers (start, tell, answer, interrupt, stop, transcript), worktree diff,pr_openwith guards,notify_user. King also gets Leon's memory and task boards (leon task mcp --anywhere, with aprojectargument).leon-turn: a turn can be given MCP servers and instructions (Claude, Codex app-server, ACP), and every adapter reports the turn's tokens.a.king.tomlover Leon's defaults (crates/leon-king/src/defaults.toml), merged key by key;leon king config [--defaults]prints it.Defaults worth a look
automode. Workers start in a mode that edits their own worktree without asking (codexauto, claudeacceptEdits), because every question a worker asks costs one of King's turns.planningtier (best models); research goes tocheap, code tostandard.Not in this PR
King on the phone,
leon king service install, workers on SSH and relay machines, terminal-only agents as workers.Testing
scripts/check.shpasses, after mergingmain(one conflict inui/shell.rs: both sides' commands kept).