worktree config: set up the CLI
Configure defaults and inspect current configuration.
worktree configworktree config <key> <value>worktree config <key>worktree config --listworktree config --list --missingworktree config --missingworktree config --missing --names <comma-separated-keys>worktree config --yes --names <comma-separated-keys>worktree config --approveworktree config --project--list shows github.token, jira.apiToken, linear.apiKey, linear.agentToken, linear.webhookSecret and clickup.apiToken as <key>=*** when set, so a listing is safe to
paste or screen-share. worktree config <key> with no value prints the current value and nothing else, secrets
included, so token=$(worktree config github.token) works in a script. A key with no value prints nothing and
exits 0.
--missing filters to values that are not configured yet.
- With
--list, it only prints config names that currently have no value. - Without
--list, it only prompts for missing values. --nameslimits prompting to specific config keys. Naming keys is asking for them, so the setup checklist is not shown and each named key is asked directly.--yes(-y) makes the run non-interactive: nothing is asked. Each key takes its default, or the value it already holds, and the run fails with exit2namingworktree config <key> <value>for a key with neither, such as a token. Without--namesthere is no checklist to answer and the run fails naming--names <keys>.
The Setup Checklist
Section titled “The Setup Checklist”A bare interactive worktree config opens with one question, “What do you want to set up?”, a checklist you
move through with the arrow keys, tick or untick with space, and confirm with enter (Esc asks whether to quit, see Quitting). The items, in order, are
GitHub, Jira, Linear, ClickUp, how worktrees open, the coding agent for --agent, branch prefixes and the
command to run after creating a worktree. A ticked item shows a filled circle and an unticked one an empty circle, so the
state does not depend on colour. An item that is already set up starts ticked, so a second run walks you through
what you have. Unticking an item only means “do not ask now”: it clears nothing, and a stored token stays in
git config.
Next comes defaultSourceBranch, which is not on the checklist and is asked unless --missing or a project file has taken it out, and then the questions of each ticked item, in the order
above. No item sits behind a gate question, so ticking nothing costs two questions at most: the checklist and defaultSourceBranch. An item is listed only while it has
a key left to ask: --missing and the keys a project file supplies take keys out before the
checklist is built, and with no item left the checklist is not shown.
Each ticked item opens with a one-line heading, such as “Setting up Jira”, so you can see which part you are in; an
item can print its heading and then ask nothing, when --missing or a stored opener has already settled its
keys, and a --names run prints no headings because it has no checklist. The
run ends with one line naming the keys it saved, for example “Configuration complete! Saved: opener, codeEditor”,
or “Configuration complete! Nothing changed.” when it stored nothing new. The line lists key names only, never a
value, so a token never reaches your screen or a pasted bug report. A key whose answer matches what was already
stored is not listed. Both read as words, without colour.
Quitting
Section titled “Quitting”Esc in any question of an interactive run asks “Quit now?”, with No as the default. Yes, or Ctrl-C at a question,
stops the command quietly and exits 0; No, enter, or Esc again takes you back to the question you were on, which
starts over from its default, so half-typed text is lost. Only a lone Esc counts: arrow keys and Alt combinations do
not, and a lone Esc takes about half a second to register while the terminal rules out a longer key sequence. When
worktree config is stopped this way it prints one line naming the keys it had already saved, by name and never by
value, such as Stopped. Saved: opener, codeEditor or Stopped. Nothing changed. What was saved stays saved, and the
offer to set up a project file is not made.
Project File
Section titled “Project File”When the repository’s .worktree.yml sets a team key, worktree config knows. See
Project Configuration for the file.
-
The wizard asks nothing the file answers. A bare
worktree configsays once which keys the file sets and skips them, including a personalpostCreatewhen the file has steps. The wizard no longer writes a personal copy of a value the file already supplies.--namesalone is the exception: naming a key is asking for it. With--missinga key the file supplies is not missing, so it is not asked even when named, which is whybranch’s offer to fill in missing values never asks for one. -
worktree config <key> <value>for a key the file sets says so, shows the file’s value and yours, and asks before writing your value. Yes overrides the file for you only. Non-interactive, naming the key and value is asking for it, so the value is set and a warning says the file sets the key. -
--listmarks where each value comes from, in plain text:defaultSourceBranch=origin/main (.worktree.yml)branchPrefix.bugfix=bug/ (overrides .worktree.yml: fix/)A value only the file supplies carries
(.worktree.yml). A value in your git config that differs from the file’s carries(overrides .worktree.yml: <the file's value>). Keys only the file can set follow, one line each:jira.branchType: 4 rules,branchType: 2 rules(the shared list),branchName=<template>,copy: 1 patternandpostCreate: 2 steps, each marked(.worktree.yml). A value the file supplies is not missing, so--list --missingleaves it out. Secrets stay masked as<key>=***.
Writing the file with --project
Section titled “Writing the file with --project”worktree config --project writes a commented .worktree.yml at the top level of the current worktree from
the team keys in your git config (defaultSourceBranch, branchPrefix.*, jira.host, jira.deployment,
clickup.workspaceId, github.repository, github.host and postCreate), with the $schema comment line first. It never writes a personal or
secret key. A personal postCreate command becomes a one-step list. The file is left uncommitted for you to
review, and the command refuses to overwrite an existing .worktree.yml. It takes no other argument or flag.
Offers
Section titled “Offers”On a terminal, branch (after the worktree is open) and a bare worktree config make two offers, each at
most once. Nothing is offered under --json, --yes, --non-interactive, CI, without a terminal, or on
branch --dry-run.
- With no
.worktree.ymlon the default branch and a team key in your git config,worktree config --projectis offered once per repository. Either answer is remembered. - With a
.worktree.yml, the keys in your local git config that hold the same value as the file are offered for removal (git config --local --unset), once per version of the file. A key with a different value stays, as the override it is.
These answers are kept under northguild.worktree.* in local git config. They are not configuration keys, so
--list does not show them and worktree config <key> <value> cannot set them.
Examples
Section titled “Examples”worktree config defaultSourceBranch origin/mainworktree config codeEditor codeworktree config opener herdrworktree config opener rexworktree config opener autoworktree config opener noneworktree config openerworktree config agent.command "claude --bg"worktree config postCreate "pnpm install"worktree config github.autoAssign trueworktree config jira.autoAssign trueworktree config jira.autoStart trueworktree config linear.autoStart trueworktree config clickup.autoAssign trueworktree config clickup.autoStart trueworktree config --listworktree config --list --missingworktree config --missingworktree config --missing --names defaultSourceBranchworktree config --missing --yes --names branchPrefix.feature,branchPrefix.bugfix,branchPrefix.choreworktree config --projectConfiguration is stored in Git config under northguild.worktree.*. A team can also set some keys for
everyone in a .worktree.yml file, which your own value overrides; see
Project Configuration.
Opener Keys
Section titled “Opener Keys”openerselects where a finished worktree opens, and forherdr,rexandautowhere its space or session is closed again when the worktree is removed:editor(default),herdr,rex,autoornone.autopicks Herdr or Rex from the terminal the command runs in, else the editor, and on removal closes the worktree’s space in whichever installed tool holds it. Withnonenothing is opened: the command printsWorktree created at <path>(Worktree already exists at <path>when it reopens an existing worktree) and stops. An unknown value fails with exit2.codeEditorthe editor executable plus any arguments, used whenopeneriseditor, and byautoas its fallback.herdr.focuswhether a new Herdr space comes to the front. Defaults totrue. Applies whenopenerisherdr, orautopicks it.herdr.agentthe agent kind that starts in every newly opened Herdr space, with or without a brief. Unset means no agent, unlessbranchorcheckoutis given a brief (--agent), in which case the programagent.commandnames is used.rex.focuswhether a Rex session’s app is brought to it when the worktree opens. Defaults totrue; onlyfalseturns it off. Applies whenopenerisrex, orautopicks it. See Rex Sessions.
opener and codeEditor are always listed. When you tick how worktrees open, the wizard asks opener
first and its answer decides what follows: editor asks codeEditor, herdr asks herdr.focus, rex asks rex.focus, auto asks codeEditor and the focus key of each of Herdr and Rex that is offered, and
none asks nothing more. auto picks Herdr or Rex from the terminal the command runs in, when that tool’s CLI is installed (Herdr first if both), and falls back to the editor; unset still means editor, and auto is offered where herdr or rex is, but preselected only when it is already your opener. herdr.agent is not asked here: it follows the coding agent’s question, described
under Agent Key. herdr.focus and herdr.agent are listed, and herdr is among
the opener’s choices, only when the herdr CLI is on your PATH, or when one of them already has a value (or
opener is herdr). rex.focus and rex as a choice follow the same rule for the rex CLI: listed and offered
only when it can be found (on PATH, in $REX_BIN_DIR, or in the Rex app bundle), or when rex.focus has a value or
opener is rex. Without those, the wizard offers editor and none only (auto has nothing to pick between, unless it is already stored). Once herdr is offered,
choosing it asks herdr.focus (and, with a coding agent, the Herdr yes/no below) even if the CLI has since gone missing, and rex likewise asks rex.focus. --names and a direct
worktree config <key> <value> always work regardless, so a machine can be configured before Herdr or Rex is
installed: --names opener offers all five choices, and each named key is asked on its own. With --missing and opener already set, the stored opener decides the follow-ups: a codeEditor is only asked under editor or auto, and herdr.focus only under herdr or auto (herdr.agent only under herdr) and rex.focus only under rex or auto.
GitHub Integration Keys
Section titled “GitHub Integration Keys”github.tokenfor GitHub API access to github.com. It is never read for, or sent to, a GitHub Enterprise host.github.autoAssignwhether reading a GitHub issue also assigns it to you:truealways,falsenever, unset means you are asked once and your answer is saved. See Configuration.github.repositorytheowner/repothat--githuband--assignuse, a team key that can also be set in.worktree.ymlundergithub:. Without itworktreeusesupstreamwhen it is ongithub.host(github.comunless set), elseorigin. The wizard never asks for it, and--missingnever lists it: most people have no fork. Set it by name, for exampleworktree config github.repository acme/widgetswhen your issues are on your fork. See Forks.github.hostthe GitHub host that--githuband--assignuse, a bare hostname such asghe.example.comfor GitHub Enterprise. Unset meansgithub.com. A team key that can also be set in.worktree.ymlundergithub:. The wizard never asks for it, and--missingnever lists it. Set it by name, for exampleworktree config github.host ghe.example.com. See GitHub Enterprise.branchPrefix.featureoptional prefix used forFeatureissues.branchPrefix.bugfixoptional prefix used forBugissues.branchPrefix.choreoptional prefix used forTaskissues.
These prefixes are chosen by each provider’s built-in mapping (GitHub and Jira by issue type, Linear by label,
ClickUp by tag). A branchType list for that provider, or the shared top-level one, in .worktree.yml replaces the mapping; see
Branch-type rules.
github.token and github.autoAssign are asked together when you tick GitHub in the checklist. The github.autoAssign prompt has three choices: “Yes, always”, “No, never” and “Ask me each
time”. The last leaves the key unset, clearing any stored answer, which is the “ask me” state — so
--missing goes on offering the prompt until you settle it either way. Leaving the github.token,
jira.apiToken, linear.apiKey or clickup.apiToken prompt empty, or answering with only spaces, keeps any token you already have,
rather than clearing it. A pasted value is stored without surrounding whitespace.
clickup.workspaceId is optional and only matters for custom task ids such as DEV-123: an empty answer skips it and writes nothing, a non-interactive run skips it rather than failing, and under --missing pressing Enter skips its prompt too.
ClickUp asks four things, in this order: the token, the workspace id, the clickup.autoAssign select and the clickup.autoStart select. Both selects have the same three choices as jira.autoAssign: “Yes, always”, “No, never” and “Ask me each time”. The last leaves the key unset, so --missing goes on offering the prompt until you settle it. A direct worktree config clickup.autoAssign or worktree config clickup.autoStart accepts only true or false; see Configuration.
A direct worktree config github.token " " (likewise jira.apiToken, linear.apiKey, linear.agentToken, linear.webhookSecret and clickup.apiToken) with a value that is only
whitespace is refused with exit 2, and nothing is stored.
Jira Integration Keys
Section titled “Jira Integration Keys”jira.host,jira.emailandjira.apiTokenfor Jira API access.jira.deploymentwhich Jirajira.hostis:cloud(the default) ordatacenter. A team key, also set underjira:in.worktree.yml, and never asked for byworktree config.jira.autoAssignwhether--jiraalso assigns the issue to you:truealways,falsenever, unset means you are asked once and your answer is saved. See Configuration.jira.autoStartwhether--jiraalso moves the issue to in progress once the worktree exists:truealways (an issue already in progress or done, or with no single in-progress status to move to, is left where it is),falsenever, unset means you are asked once and your answer is saved. See Configuration and Moving the issue to in progress.
When jira.deployment is datacenter (from git config or .worktree.yml), the wizard does not ask for jira.email, a bare run, --missing and --list --missing do not count it as missing, and the token prompt reads “Jira personal access token” and shows the steps for creating one in Jira instead of the Atlassian Cloud ones. The token still goes in jira.apiToken. See Jira Data Center. With cloud or unset, nothing changes. Naming jira.email with --names still asks for it, unless --missing is also given.
The Jira keys are asked together when you tick Jira in the checklist. The jira.autoAssign prompt is asked after the token
and has the same three choices as github.autoAssign: “Yes, always”, “No, never” and “Ask me each time”.
The jira.autoStart prompt follows it with the same three choices. “Ask me each time” leaves a key unset,
so --missing goes on offering the prompt until you settle it. A direct worktree config jira.autoAssign or
worktree config jira.autoStart accepts only true or false.
Linear Integration Keys
Section titled “Linear Integration Keys”linear.apiKeyfor Linear API access.linear.autoStartwhether--linearalso moves the issue to a started state once the worktree exists:truealways (an issue already started, or in triage, completed, canceled or duplicate, is left where it is),falsenever, unset means you are asked once and your answer is saved. See Configuration.
The Linear keys are asked together when you tick Linear in the checklist. The linear.autoStart prompt is asked after the key
and has three choices: “Yes, always”, “No, never” and “Ask me each time”. The last leaves the key unset, so
--missing goes on offering the prompt until you settle it. A direct worktree config linear.autoStart
accepts only true or false.
Three more Linear keys are for a Linear agent that starts worktrees, and worktree linear-listen reads them. None is asked
by the wizard (a bare run and --missing skip them), and none can be set from .worktree.yml: set one with
worktree config <key> <value>.
linear.agentTokenthe Linear agent app’s OAuth token. Secret:--listshows it as***.linear.webhookSecretthe signing secret of the app’s webhook. Secret:--listshows it as***.linear.agentAllowthe Linear user ids allowed to delegate an issue to the agent, comma-separated.linear.agentContexttrueorfalse(anything else is refused with exit2).trueletsworktree linear-listenadd the delegated issue’s text to the agent’s brief, fenced as untrusted and capped. Unset meansfalse. Neither the wizard nor.worktree.ymlsets it.
Agent Key
Section titled “Agent Key”agent.commandthe command--agentruns to hand a brief to a coding agent. It does not start an agent on its own: without a brief, onlyherdr.agentdoes. The wizard asks for it when you tick the coding agent in the checklist, as one question, “Which coding agent do you use?”, with the stored command filled in; leave it empty for no agent. Whenopenerisherdrand there is a command, one yes/no follows: “Start it in every new Herdr space, even without--agent?”. Yes setsherdr.agentto the command’s first word, unlessherdr.agentalready has a value, which it keeps (a first word that is not a valid kind, such as a path, is not stored: no question is asked and the wizard points toworktree config herdr.agent <kind>); no leavesherdr.agentempty. Left empty with a kind already inherdr.agent, the yes/no is instead “Keep starting<kind>in every new Herdr space?”, since that kind would otherwise still start in every new space: yes, the default, keeps it, and no empties it.--names herdr.agentand--names agent.commandstill ask for each key on its own. Read bybranch --agentandcheckout --agent, bylist --agents, and bycleanup’s agent check. See Configuration.
Post-create Key
Section titled “Post-create Key”postCreatea command to run in every new worktree, such aspnpm install. Read bybranch; when it is unset the steps underpostCreatein.worktree.ymlrun instead (after you approve them), else the command is inferred from the lockfile. It is validated likeagent.command: its first word has to be onPATH. See Configuration. The prompt accepts an empty answer, which leaves it unset.
Approving Post-create Steps
Section titled “Approving Post-create Steps”worktree config --approve shows the postCreate steps in the repository’s .worktree.yml and asks
whether to run them in new worktrees on this machine. Yes records the approval for those exact steps in this
clone’s local git config, so worktree branch does not ask. It needs a terminal: when nothing can be asked
it refuses with exit 2. The approval is not a configuration key, so it is not listed by --list and
cannot be set by name. See Approving the steps.