Skip to Content

Herdr Spaces

By default a new worktree opens in your editor. If you work in Herdr , a terminal workspace manager, you can have it land as a Herdr space instead — labelled by branch, optionally with an agent already running in it.

The worktree itself is created exactly as before. Only the final step changes.

Requirements

  • The herdr CLI on your PATH.
  • A running Herdr server.

Without the herdr CLI, worktree config neither lists nor prompts for any of the keys below — the feature is invisible until Herdr is installed. You can still set one explicitly by name, which is what to do if you are configuring a machine ahead of installing Herdr:

worktree config opener herdr # works whether or not herdr is installed yet worktree config --missing --names opener # prompts for it regardless

Switch the opener

worktree config opener herdr

opener accepts editor, herdr or none. Unset means editor, so nothing changes for anyone who does not set it.

The key is stored in local Git config under northguild.worktree.opener, so it applies to one repository. Set it again in each repository you want it in.

Now worktree branch, worktree checkout and worktree open all hand the finished worktree to Herdr:

worktree branch feature/add-bulk-actions

The space is labelled with the branch name — feature/add-bulk-actions, not the repository name — so several worktrees of the same repository stay distinguishable in the sidebar.

Re-opening a worktree that already has a space reuses it rather than creating a second one, and switches to it unless you have turned focus off below.

When the worktree is removed, its space is closed again — see When the worktree goes.

Focus

The space comes to the front by default, because every command that opens a worktree is you asking to be taken to it. To leave it in the background:

worktree config herdr.focus false

Start an agent with the space

Optional, and off unless you set it (or give worktree branch a brief, below):

worktree config herdr.agent claude

The value is the agent kind Herdr should start — claude, codex, gemini and so on. Run herdr agent start --help for the kinds your Herdr accepts; worktree does not keep its own list, so a kind added by a Herdr release works immediately, and an unknown one is rejected by Herdr with its own message.

The agent starts only for a space this command just opened. Re-opening a worktree does not start a second agent, because the one you left running is still in that pane.

Herdr’s name for the agent is derived from the branch and coerced to what Herdr accepts, which includes a 32-character cap. If the start fails — most often a name already taken by a live agent from another repository — you get a warning, and the space is still open and correct.

This is the agent for the worktree: worktree branch --agent "<prompt>" does not start a second one beside it. Whenever Herdr starts an agent:

  • agent.command’s arguments are passed to it when it names the same program, with --bg and --background dropped, because the agent runs in the pane.
  • For claude, --name <repo>-<branch> is added, lowercased and never shortened, and printed on stderr.

With a brief (--agent, --agent-file or --agent-stdin):

  • The kind is herdr.agent, or else the program agent.command names, so you can leave herdr.agent unset. With a brief and neither, worktree branch exits 2 before it creates anything and names the key to set. Without a brief, only herdr.agent starts an agent.
  • The brief is submitted with herdr agent prompt once the agent is ready, never as part of herdr agent start.

--no-agent opens the space without an agent, and --no-open skips Herdr for the run.

When the worktree goes

worktree remove and worktree cleanup delete a checkout. With opener herdr they also close the Herdr space that was built around it, so a space does not outlive the worktree it belongs to.

worktree remove feature/add-bulk-actions
✔ Worktree feature/add-bulk-actions was removed. ✔ Closed Herdr space feature/add-bulk-actions

Only worktrees that were actually removed. A branch that was not found, a confirmation you declined, a removal that failed, any worktree cleanup held back — for uncommitted changes, a live agent, or unpushed commits it could not count — none of those close anything. Their checkouts are still on disk, and a space with no window into a checkout that still exists is worse than one left open.

Only this repository’s spaces. The lookup is scoped to the repository you are in, and the space your own checkout is open in — the window you are sitting in — is never one of the candidates.

A worktree with no space open is not an error and prints nothing. Neither is a repository you have never opened in Herdr.

worktree cleanup --ignore-agents is sharper than it was. The flag gathers no agent sessions, so a worktree an agent is living in is not held back — and closing its space now takes down the panes that agent is working in. That is the cost of “do not look”, and it is larger than before spaces were closed. Without the flag, an agent that is working holds its worktree back, and its space with it. One that is only idle does not.

When Herdr cannot be reached

Every call to Herdr is bounded, so a Herdr that accepts the connection and then never answers fails with a line saying so rather than hanging the command. Ten seconds for an open, a lookup or a close; longer for starting an agent, because Herdr itself holds that request open while the agent boots.

Opening

If herdr is not installed, the server is not running, or the open fails, worktree prints what Herdr said and where the worktree is:

✖ Herdr: `herdr` was not found on your PATH. The worktree is at /path/to/repo.worktrees/feature/add-bulk-actions

A call that times out reads the same way, naming the command and how long it waited:

✖ Herdr: `herdr worktree open --path /path/to/repo.worktrees/feature/add-bulk-actions --cwd /path/to/repo --label feature/add-bulk-actions --focus` did not answer within 10s.

It does not fall back to your editor. Setting opener herdr is a deliberate choice, and an unexpected editor window is not a useful consolation prize.

The command still exits 0. By the time the opener runs, the branch, the worktree and the copied env files all exist — the only thing that failed is the last step. The exception is a run given a brief (--agent): if no agent ends up with it, the run exits 1, because the agent working on it was part of what was asked for.

Closing

A failed close is a warning and nothing more — including a timeout, which is a warning here rather than the error it would be on the way in:

⚠ Herdr: workspace wQ not found (workspace_not_found) ⚠ Herdr: `herdr workspace close wQ` did not answer within 10s.

The command still exits 0, but for a different reason than above, and the difference is worth knowing. At open time the last step failed and everything before it succeeded. At close time the worktree is already deleted, the branch is gone and git worktree prune has run — so there is nothing to retry and nothing to undo. A non-zero exit would claim the removal did not happen when it did.

What is left behind is a space with no checkout under it, which you can close from Herdr’s own sidebar. Each space is closed independently, so one failure does not take the rest of a worktree cleanup with it. If the lookup itself fails, you get one warning and no spaces are closed — the removals still happen.

Configuration reference

KeyValuesDefault
openereditor, herdr or noneeditor
herdr.focustrue or falsetrue
herdr.agentan agent kind, such as claudeunset — no agent
Last updated on