Agents
Where an agent works, how its work gets a name, and how finished work comes home
Alt+N starts an agent: choose the directory it works in, and Enter starts
it with the harness you used last (← → change it). Each agent is a tab in
the sidebar.
Where an agent works
By default an agent works in your project, on your branch, like you would.
Or it gets a worktree of its own: a separate checkout of the repository
under .worktrees/, on a branch of its own. Two agents can then never touch
each other's files, or yours.
-
One agent: right-click it → To worktree. It moves to its own worktree and takes your uncommitted changes with it, as a copy. When the tree holds uncommitted work, To worktree, no changes cuts the worktree from the last commit instead and leaves the changes where they are.
-
Every agent in a project: declare it once in
agents.yaml:workspace: worktree: always # manual (default) | always
A new agent's worktree starts from your target branch as the remote last had
it (origin/main), so it is not born behind work that already merged, even
when your own main has not been pulled. When your local branch carries
commits the remote does not, it starts from yours.
Checkouts are reused, so a second agent does not pay for a fresh
node_modules/ or a cold build. An agent that ends never keeps its
checkout: whatever it left uncommitted is kept for it, its commits stay on
its branch, and the checkout goes to the next agent. So a project keeps as
many checkouts as it had agents working at once, and one nobody used for
three days gives its disk back. A checkout only subagents used goes the next
time uze tidies up, since it holds no build worth keeping warm. The age for
free checkouts is yours to change:
workspace:
idle_days: 3 # after this long unused, a free checkout goesAn agent that ended leaving nothing behind (no checkout, no branch, no unfinished work) stays listed in recent for 30 days, so you can go back to its conversation, and is then forgotten along with that conversation.
An agent always comes back to the same directory, .worktrees/<agent>,
because every harness keeps its conversation by directory: resume an agent
days later and it picks up the conversation it left. When a checkout goes
to another agent, uze renames it to that agent's directory, and the build
cache goes with it. A cache that records its own absolute path, such as a
Python virtualenv, a direnv allow list or a CMake build tree, needs
repairing after that. setup runs every time an agent takes a checkout, so
that is the place to do it. Antigravity asks you to trust each agent's
folder the first time it opens there.
A checkout is only ever reused or removed when uze made it, and never while something is still working in it. A worktree you or a tool added by hand is shown, never touched.
A project has no workspace: section until somebody chooses something: the
agents.yaml uze creates says nothing about the workspace, and every key is in
the reference. Whatever is chosen,
or the defaults when nothing is, each agent the workspace launches is told
what applies to it when it starts: how to name its work, which checkout and
branch it is in and how its work is delivered. It arrives with the agent's
context, the way AGENTS.md does, and nothing is written into your files: an
edit to agents.yaml reaches the next agent you launch.
The agents themselves carry the part no harness does for them with the
uze:worktree skill.
Naming a project
Each agent's row names the project it works in, by its directory. To call a
project something else, double-click that name, or right-click the agent and
pick Rename › Project, then type the new name and press Enter. Every
agent of the project reads it, in their own checkouts too. Rename ›
Agent renames the agent itself.
The name stays on this machine, in ~/.uze/config.toml, and never reaches
the project:
[projects."/home/you/work/app"]
label = "billing api"Leave the name empty, or give it the directory's own, and the directory's name is back.
Launching with other flags
Alt+→ in the new agent popup opens its overrides: extra flags for the
harness and NAME=value variables, for this launch only. Type them as you
would on a command line; Tab completes from the flags the harness itself
defines. Flags and variables you used before are listed under the line, this
project's first: Space checks one for this launch, and ✕ forgets it. The
next new agent opens with the set the last one launched with.
What uze manages itself is refused as you type: its own UZE_* variables,
PATH, HOME, the agent's config directory, and the flags for sessions and
resuming. Flags that weaken the harness's safety, such as
skipping permission prompts, are accepted and marked. Variables that look like
secrets, and URLs carrying credentials, are never remembered.
An agent keeps its overrides when it restarts or resumes.
Restarting with other flags
Right-click the agent (or press Alt+.) and open Restart in ›. A panel
opens beside the menu on the harness the agent runs, holding the flags and
variables it was launched with. Change them as you would for a new agent and
press Enter: the agent restarts in the same directory and resumes its
conversation with them. Enter says what it will do: restart, close when
nothing changed, or continue in another harness. If the agent is in the
middle of a turn, uze asks before interrupting it.
Continuing in another harness
When a harness stops being able to work, for example because it hit its
usage limit, open Restart in › and move the panel's harness (← →
with nothing typed, or its arrows) to Codex, or any other harness set up
on this machine. The same agent carries on in the same directory, on the
same branch, under the same name, with the flags it last had on that
harness.
The harness it leaves keeps its conversation. Switch back later and that harness picks up exactly where it was.
The harness taking over cannot read another vendor's conversation, so uze writes it a briefing: what the agent was asked, what it said last, the last command it ran, its commits and its uncommitted files. Its first message points at that file, once; a restart does not repeat it. Switching back to a harness that ran before briefs it only on what happened since it left. The briefing stays out of your checkout and is readable by you alone. Claude Code and Codex conversations are read in full; from OpenCode and Antigravity CLI the briefing carries what Git says.
Its work gets a name
Every agent names its work as the first thing it does, like
fix/login-timeout. That name is what you read in the sidebar. In a worktree
it is also the branch, so it is what a reviewer sees on the pull request; in
your own checkout only the label changes, and your branch keeps its name.
Work that reaches its first commit still unnamed is named from that commit's
subject. You never have to name anything, and workspace.branch in
agents.yaml sets the vocabulary names are judged against (by default the
Conventional Commit types).
Where it stands
The tab shows where the work is, read from Git rather than from what the agent says:
| uncommitted | Changes in the checkout, not committed |
| ready | Commits ahead on a clean tree, ready to deliver |
| published | On the remote and level with it, no request yet |
| in review | A request is open for it, shown by its number (#41) |
| delivering | The rebase, the checks and the merge or push, in flight |
| conflict | The rebase stopped; it is settled in the checkout |
| checks failed | The checks failed on the rebased commits |
| delivered | The work is in your target branch |
| unfinished | No agent left; its work is kept for it |
An agent working with nothing to report yet shows no mark. Click any mark in the sidebar for this legend.
Bringing the work home
When an agent in a worktree is ready, press Alt+I or click its status
(→ main ↑3) to deliver it. The branch is
rebased onto your target branch, your checks run, and then the work goes where
the project says:
workspace:
delivery: push # merge | push; undeclared, nothing is delivered
gate: npm test # the checks that must pass first
actions:
on_change: Commit what you have with a message that says why.
on_publish: Open a pull request for this branch against main, then end your turn.
on_conflict: The rebase is paused here. Resolve it, run git rebase --continue and the checks.
on_fail: The checks failed after the rebase. Fix them and commit.- merge fast-forwards your local target branch.
- push pushes the branch to the remote. No pull request is opened.
Delivering again later brings a published branch up to date with the target,
and F1 also offers Deliver all, for every agent in the space that is
ready.
What the agent is asked next is the project's own words, under actions: one
line per state (on_change for uncommitted work, on_publish, on_conflict,
on_fail), sent into its pane when uze leaves the work in that state, and
whenever you click the status in the tab strip. A line is never sent while the
agent is working or over something you typed: uze says so instead. on_change
also makes uncommitted work show as a status you can click. If the checks fail
or the rebase conflicts, nothing reaches the target, and the agent is sent the
project's line for that state, or uze's own when the project declares none.
See actions.
The checks, like setup, are commands from the repository, so uze runs them
only after you approve them. The first time the workspace opens a project that
declares any, it shows a Review button: read the exact lines, then approve
them or not. Until you do, worktrees are prepared without setup and delivery
waits. If someone changes the lines later, the workspace asks again. From a
terminal, uze workspace allow does the same, and uze workspace revoke
takes the approval back; see
Approving the commands.
Repository hooks never run in uze's own Git, so a pre-push hook (Git LFS,
lefthook) does not run when uze pushes. Put those checks in gate. See
Security.
Subagents
An agent that splits its work across subagents asks uze for a checkout for each one, cut from its own commit, and brings their commits back onto its branch when they are done. You do nothing: the agent does it, the way it names its work (Agent CLI).
The subagent's checkout comes from the same pool, so it starts warm. Joining replays its commits onto the agent's branch with no merge commit. The checkout stays until it is joined or the agent ends, and is then removed the next time uze tidies up (its branch stays). An agent is not delivered while a subagent still holds work.
Work nobody finished
Close an agent with work it never delivered and the work is kept, never lost,
and never in the way. Its commits stay on its branch; whatever it left
uncommitted, including new files, is kept on a shelf, a commit of its own
under refs/uze/shelf/ that touches neither the branch nor git stash. Its
checkout then goes to the next agent. A shelf lives in your repository and
nowhere else: git push --mirror or a push refspec of refs/* would publish
it, so keep those away from a repository you work in this way.
A checkout is kept as it is only while something still needs it there: a rebase or merge Git has paused in it, a process working inside it, or work a shelf cannot hold, such as a submodule with changes of its own. Every other checkout goes back to the pool on its own, and one whose work is already in the target is cleaned up without you asking.
Recent
Alt+P, or a click on work at the top of the sidebar, turns the sidebar
into recent: the agents no pane carries, across every project uze has
recorded, one line each with how long ago it last changed. It lists the agents
that have a name; a shows the unnamed ones too, and / searches by name,
branch, project or state. Press Alt+P or Esc to go back to the tree.
Agents that wait on you come first, under needs you:
- a rebase paused on conflicts, or checks that failed,
- uncommitted changes,
- a subagent ready to be joined into its agent,
- work ready to deliver.
The rest follow under others: work being delivered, published or with the reviewer, shelved work, delivered work, agents that worked in your own checkout, and agents that never changed anything. Each group is newest first. Select a row and it says why it is listed, which project it belongs to and the space resuming it opens in, its branch, how far it is ahead and how much disk its checkout takes. A checkout is never a row of its own: it is a fact about the agent that left it.
Enter does the one thing that moves the selected agent on. For a subagent it
joins its commits into its agent's branch. For anything else it resumes the
agent with a new tab: it goes back to the checkout it left when that one is
free, or to any other (an agent that worked in your own checkout goes back
there), with its shelf put back as uncommitted changes and its
subagents beside it. It opens in a space that already works in its project, or
else in the space you are looking at; resuming never creates a space.
Ready work also offers i to deliver it. Right-click a row, or press
Alt+., for the same actions as a menu.
d discards the selected agent's work: its branch, its shelf, any checkout it
still keeps and its conversation. It asks first, with the keyboard on
cancel. Where there is no work left to lose (work already delivered, an
agent that worked in your own checkout, or a project no longer on disk), d
forgets the agent instead: it removes uze's record and its conversation, and
touches nothing else on disk.