Skip to content

Code agents

A code agent is something that can read your codebase and make changes to it. A workspace can have several, and they’re configured at Dispatch in the sidebar (/w/<workspace-id>/<slug>/dispatch). Seeing the page needs dispatch.read; changing it needs dispatch.manage.

There are three kinds, and where an agent runs decides everything else:

Where it runs How work lands
Claude Code on a machine you control, connected to your workspace commits or a pull request, as your policy says
Codex on a machine you control, connected to your workspace commits or a pull request, as your policy says
GitHub Copilot GitHub’s own service always a pull request

Claude Code and Codex are the same local setup — one piece of software on your machine, told which CLI to drive. They differ only in the model doing the work, so everything below applies to both. You can run one of each in the same workspace and address them separately by name.

The local agent is open source at VroxyAI/vroxy and installs with one line — see installing one. The Copilot path needs no software of your own; see Feedback to fix for the GitHub App setup it depends on.

Adding an agent creates a team room named after it, and that’s where you talk to it — from the web app or the mobile app, the same as talking to a colleague. Ask a question about the code and it answers in the room; ask for a change and it makes one.

You can also reach an agent from any room by starting a message with its slash command. An agent named “Claude Code” answers to /claude-code. Typing / in a room composer lists the commands that room accepts, so you don’t have to remember them.

The command only works at the start of a message — a slash in the middle of a sentence is left alone.

Each room chooses which agent answers it, or inherits the workspace default. A room set to Off never wakes an agent; When mentioned answers only when the agent is @-mentioned; Every message answers everything a person says there. Automated webhook posts never trigger a reply unless they explicitly mention the agent, so a build-notification room doesn’t get answered once per deploy.

An agent works on one or more targets — an environment, each with its own base branch.

For a Copilot agent, a target is a repository, and one agent can cover several. Tick the repos you want when you configure it. Each one keeps the base branch it was linked with, so an agent can open PRs against master in one repo and main in another without you thinking about it.

For a Claude Code agent, a target is a checkout on the machine running it. Those appear on their own — the agent reports what it’s working on when it connects, and the row shows up.

When an agent covers more than one target, a room has to say which one it works on. Pick it in the room’s settings. If you don’t, the agent replies asking you to choose rather than guessing — work landing in the wrong repository is a worse outcome than a question.

Removing a repo from an agent retires that target rather than deleting it, so anything already filed against it keeps its history.

For a Copilot agent the answer is always a pull request — that’s the only thing Copilot produces.

A Claude Code agent is governed by a ship policy, set for the workspace under Settings → Dispatch and overridable per target:

  • Always commit to the base branch — the change lands and deploys.
  • Always open a pull request — nothing lands until you merge.
  • Decide by size (the default) — small changes commit, larger ones become a pull request.

“By size” routes to a pull request when any one of these is true, and one is enough:

  • more files changed than your file threshold (3 by default)
  • more lines changed than your line threshold (80 by default)
  • the change touches a path you’ve marked as always-reviewed (db/migrate/* by default — a schema change shouldn’t land without a person looking at it)
  • the request explicitly asked for a pull request

You can also set a branch prefix, open pull requests as drafts, and turn on auto-apply, which lets a change the policy sizes as small ship without anyone clicking approve. Auto-apply is off by default and never applies to anything routed to a pull request.

Every per-target field can be left blank to inherit the workspace setting, and a target can be disabled entirely — the agent then refuses to apply anything for it.

Two things have to be true, and both are checked:

  1. You can use that kind of agent. Sending work to Copilot files an issue in your repository and bills the task to the sender’s own Copilot plan, so it’s restricted to admins and owners by default.
  2. You meet that agent’s own minimum level. Each agent carries a level of its own, so you can keep one open to the whole team and another restricted.

If you’re not allowed, the agent says so in the room. It doesn’t silently ignore you — an agent that stays quiet is indistinguishable from one that’s broken.

Open the members panel of any room the agent sits in and it shows what it’s doing right now: the message it’s working on, who asked and where, and how long it’s been going. The message is a link — clicking it jumps straight to that point in its room.

Stop ends the current run. Resuming afterwards picks the session back up from its last completed step rather than the exact moment it was interrupted, which is why it asks before doing it. Stopping needs permission to post in rooms; someone who can only read can watch but not intervene.

Underneath sits Up next — everything queued behind the current run, numbered in the order it will be taken. Each item says what it’s waiting on:

  • waiting — queued normally.
  • held — the lane is paused, either by hand or because the agent asked a question (below).
  • waiting for its box — the agent is a local one and the machine it runs on isn’t currently connected. The work isn’t lost; it goes out when that box reappears.

An item marked promoted was moved up the queue. Your own queued messages can still be edited from here until they start — fixing a typo in a request that hasn’t run yet beats sending a correction the agent has to interpret.

Beside the current run, a local agent names the coding CLI actually driving it and the machine it’s on:

claude 2.1.3 on build-01

The harness is the one the agent is configured to run, not merely one that happens to be installed — a box with four CLIs on it still reports the single one doing the work. That matters when a workspace has agents on more than one machine and you need to know which to look at, or when an answer looks wrong and the first question is what produced it.

The hostname is part of the same telemetry as the inventory below, and turning that off takes it too.

An agent that needs a decision can ask it as buttons rather than making you type an answer: a single choice, several checkboxes, or a text box. The options are always ones the agent declared — nothing is scraped out of the words of its message, because agents write numbered lists constantly and every one of them would otherwise turn into fake buttons.

Answering posts an ordinary message in the room replying to the question, so a clicked answer and a typed one are the same thing by the time anyone reads back the conversation. A question that’s been answered, or that expired after a day, stays visible as history with its controls gone — a settled question is a record, not a button.

Because a question is usually blocking, the queue can hold while it waits for you. Set how long under Hold the queue when an agent asks a question in workspace settings; 0 means never hold. When you answer, the hold lifts immediately and your answer jumps the queue rather than going to the back of it — you were the thing it was waiting on. A pause you set by hand is never lifted by an answer.

The agent tells you in the room, rather than nothing happening:

  • No agent configured for this room — pick one in the room’s settings, or set a workspace default.
  • Several agents and no default — nothing is guessed; choose.
  • No repository linked — add one on the agent’s page.
  • Covers several repos — pick which one this room works on.

What a local agent reports about its machine

Section titled “What a local agent reports about its machine”

A local agent sends a heartbeat every 20 seconds so the workspace can show whether it’s reachable, what it’s working on, and which version it’s running. Alongside that it reports which coding CLIs are installed on that machine, their version numbers, and the machine’s hostname — so you can see at a glance what the box could be driven with, spot one running an old build, and know which machine to go to, without logging into any of them.

It reports names, versions and the hostname only. Not paths, not file contents, not anything about the code it works on, and never any credential.

This is on by default. To turn it off, set DISPATCH_TELEMETRY=0 in the agent’s environment and restart it. The inventory already stored for that agent is then deleted, not merely frozen — switching it off means the data stops existing, not that it stops being refreshed. Everything else in the heartbeat carries on, because that’s what keeps the agent reachable and routable rather than describing its host.

Removing an agent leaves its room and every message in it alone. A configuration row shouldn’t take a conversation with it.