Agents Talking to Agents
luvus lets one agent give work to another. Because the server owns every pane’s terminal, “send a prompt to another agent” means luvus pastes the text into that agent’s input and submits it, then reports back its detected state. There is no separate message channel: the target agent’s own input is the channel, and the host is the broker.
Every pane already has $LUVUS_PANE_ID and $LUVUS_SOCKET_PATH injected, so an
agent running inside a pane can drive its neighbors with the same luvus
commands you would type yourself.
The commands
Section titled “The commands”luvus agent list # every live agent: name, pane, kind, status, cwdluvus agent name reviewer # alias the current agent (or --pane <id>)luvus agent send reviewer "Review the diff" --wait --until idle --timeout 600luvus agent read reviewer --lines 120 # read what it producedluvus agent keys reviewer enter # answer a blocked approval (esc, ctrl+c, up, ...)A <target> is one of three things:
- a live name you set (grammar
[a-z][a-z0-9_-]{0,31}), set withagent nameorpane name, - a pane id (the
panefield fromagent list), - an agent kind (
claude,kimi,codex, …) when exactly one agent of that kind is running. Two of the same kind is ambiguous, and the error names the candidates so you pick a pane id or a name.
agent send and agent keys only target a pane that is actually running an agent, so a plain shell is refused.
For line-specific feedback, the native DIFF review uses the same target validation. It groups selected local notes into one bounded message, quotes source context as untrusted review data, and records delivery without resolving the notes.
How to tell two of the same kind apart
Section titled “How to tell two of the same kind apart”Run luvus agent list (each row has pane, agent kind, name, cwd, workspace_name). Two Claudes share the kind claude but differ by pane id and folder. Give each a name so you can mention it:
luvus agent name api --pane 1 # or run `luvus pane name api` inside that paneluvus agent name web --pane 4luvus agent send api "add the /health endpoint" --waitThe AGENTS sidebar also shows each agent’s delegation token on its second line:
=name once you name it, otherwise =<id>.
A delegation, end to end
Section titled “A delegation, end to end”Start an agent in a sibling pane, name it, hand it the task, and collect the result:
new=$(luvus pane split "$LUVUS_PANE_ID" | jq -r .result.pane) # split beside youluvus pane focus "$LUVUS_PANE_ID" # keep your own focusluvus pane run "$new" codex # launch the agentluvus wait agent-status "$new" --status idle --timeout 60 # wait until it is readyluvus agent name codex --pane "$new" # give it a name
luvus agent send codex "Implement the CSV parser in src/parse.rs and add a test." \ --wait --until idle --timeout 600 # send and waitluvus agent read codex --lines 120 # read the resultagent send --wait blocks until the agent settles, using luvus’s screen-based
detection (idle, working, blocked, done). Treat those as strong hints,
not a hard contract. If a send returns while the agent is blocked, inspect it
with agent read and answer with agent keys.
Hand off (the default), or wait
Section titled “Hand off (the default), or wait”By default, delegation does not block the sender. luvus agent send without
--wait returns the moment the prompt is queued, so the sender is free. The
clean pattern is: name yourself, send without --wait with a report-back
instruction, then end the turn.
luvus agent name lead # a name the worker can reply toluvus agent send codex "Build the parser. When done, run: luvus agent send lead 'done: <summary>'"The sender is not blocked; it picks the task back up only when the worker runs
that agent send lead … and hands it back.
Wait only when you ask for it. Add --wait when the very next step needs the
result in the same reply:
luvus agent send codex "Build the CSV parser and add a test." --waitluvus agent read codex --lines 120--wait blocks the sender until the worker settles, but it is safe: a
stall guard returns stalled (exit 3) if there is no response within ~5s,
and it is bounded by --timeout (default 300s, exit 2 on timeout; exit 0 on
settle). So a broken worker never traps you — but since it blocks, reach for it
only when you actually need to wait.
The = shorthand
Section titled “The = shorthand”With the skill installed you rarely type the commands. Write =name at the start
of a line and the rest of it goes to that agent:
=codex add tests to src/parse.rs=reviewer take a look at the diff=7 run the migration=codex addresses the pane named codex. An agent name or a pane id work the same
way, so =reviewer and =7 both resolve. The same targets agent send takes.
The marker is recognized only as the first non-whitespace character on a line,
so equations and shell assignments do not trigger delegation. Codex keeps $
for invoking skills such as $luvus or $changelog.
It is a hand-off, not a wait: the agent you typed into keeps working, and the answer comes back when the other one is done. Ask for it to wait and it will.
If the name does not resolve, the agent runs luvus agent list to find it or
asks you which pane you meant.
Opt in to the skill
Section titled “Opt in to the skill”The commands above work without an agent skill. The optional skill teaches a coding agent when and how to use them. Luvus does not install skills, edit agent configuration, or make a skill-network request during startup. Enable only the agents you want:
luvus skill enable claudeluvus skill enable codexluvus skill enable opencode# or make the same explicit choice for all threeluvus skill enable --allEach agent receives its native skill directory:
- Claude Code:
~/.claude/skills/luvus/ - Codex:
~/.agents/skills/luvus/ - opencode:
${XDG_CONFIG_HOME:-~/.config}/opencode/skills/luvus/
Luvus does not add a global AGENTS.md pointer. Supported agents discover the
skill from their native directory and load its full instructions only when the
skill is relevant or explicitly invoked.
luvus skill enable installs prompt guidance. It is independent from
luvus integration install, which adds only the session/status hook needed for
precise detection and resume. Enabling either one never enables the other.
The messaging commands themselves work with every agent luvus detects (claude, codex, gemini, opencode, kimi, grok, aider, and more), whether or not that agent has the skill installed. The skill just teaches an agent to reach for them on its own.
Inspect the local state or the installed instructions:
luvus skill status # all supported agentsluvus skill status codex # one agentluvus skill show codex # installed SKILL.mdRefresh one enabled agent, or every enabled agent, between application releases:
luvus skill update codexluvus skill updateUpdates use a signed manifest, verify the package hash and every file hash, and
replace only installations that Luvus already manages. If no agents are
enabled, luvus skill update is a local no-op with no network request.
Disable an agent explicitly with luvus skill disable codex, or use --all.
Luvus removes only an unchanged managed installation. If its files were edited,
the command preserves them and reports the conflict.
When upgrading from Bohay or an earlier Luvus build, version 0.11 performs one
local, idempotent cleanup: it removes only the old delimited Codex/opencode
AGENTS.md pointer and exact known auto-installed Claude files. Surrounding
user instructions, modified files, and independently installed plugins are
preserved. The migration leaves every new skill disabled; opt back in with the
commands above.
Restart your coding agent so it loads the skill, open it in a luvus pane, and ask in plain language:
Have codex implement the parser in the other pane and tell me when it is done.
The agent recognizes the request, runs the agent send/wait/read loop
itself, and reports back. The skill also controls workspaces, tabs, panes, and
other Luvus surfaces when asked. It stays out of the way when the request is
unrelated to Luvus.
Naming renames the pane
Section titled “Naming renames the pane”luvus pane name <name> (and its synonym luvus agent name) does two things: it
sets a live address for the CLI and API, and it renames the pane’s title
strip to that name in place of its cwd path, so a named pane is easy to spot.
It shows the same delegation token in the AGENTS sidebar (=name).
A name is keyed to the pane, so it survives the agent restarting inside it and is
dropped only when the pane closes. It does not change the pane’s tab label,
which is still luvus tab rename. Clear a name with
luvus pane name --clear.
See also
Section titled “See also”- Scripting luvus for the wider CLI and the event stream.
- Multi-Agent Orchestration for the task board, path leases, and isolated worktree workers when you want a coordinated team rather than one-off handoffs.
- CLI Commands for the full
agentcommand set.