Linear Issue Integration
worktree can derive branch names directly from Linear issues in your Linear workspace.
Basic Usage
worktree branch --linear ENG-123
worktree branch --linear eng-123
worktree branch -l ENG-123Pass the issue identifier, the team key and number Linear shows on the issue (ENG-123). It is accepted in any
case. A pasted issue URL is not accepted.
The generated branch name is shown as the default in the prompt, so you can accept it or edit it before creation.
--linear cannot be combined with --github, --jira or --clickup. --assign does not work with --linear:
assigning a Linear issue is not supported yet, so the flag warns Assignment is not supported for Linear issues yet.
and the worktree is still created. Moving the issue to a started state is supported, see
Moving the issue to started.
How Branch Names Are Built
- Read the issue’s identifier, title and labels from the Linear API.
- Sanitize the title into a branch-safe slug, cut to at most 48 characters at the last dash so it ends on a whole word. A single word longer than 48 characters is cut at 48.
- Prepend a configured prefix chosen from the issue’s labels.
The name is the prefix, the identifier and the slug, for example fix/ENG-123-fix-login-redirect. Keeping the
identifier in the name is what lets Linear’s GitHub integration link the branch to the issue. A long title is cut:
ENG-124 titled “Login redirect loops forever when the session cookie expires during checkout” becomes
fix/ENG-124-login-redirect-loops-forever-when-the-session.
Linear has no issue type, so the prefix comes from the issue’s labels. Labels are compared by exact name, ignoring case:
- a
buglabel ->branchPrefix.bugfix - otherwise a
choreormaintenancelabel ->branchPrefix.chore - otherwise (a
FeatureorImprovementlabel, any other label, or none) ->branchPrefix.feature
When an issue carries several of these labels, bug wins. A label such as bugfix or Bug fix is not bug,
so it does not match.
If a prefix key is not configured, no prefix is applied.
That mapping applies only when no linear.branchType rules (or shared top-level branchType rules) are set. A
linear.branchType list, or the shared list, in .worktree.yml replaces it: the rules can match the issue’s Labels by name or by { id: ... }, and an issue
no rule matches gets no prefix unless the list ends with - otherwise: <kind>. See
Branch-type rules and
Branch name template.
What Is Read From the Issue
Issue content is used for the branch name and nothing else. worktree reads the issue’s identifier, its title
and the names of its labels (and, when linear.branchType or the shared branchType is set, their ids). The title is reduced to lowercase letters, digits and - before it becomes part of
the branch name, and the labels only select one of the configured branchPrefix.* values, or none. The issue
description and comments are never requested, never printed, never written to the --json document (whose issue
field carries only the provider, the identifier and the URL) and never passed to an agent.
With --json, issue is {"provider":"linear","key":"ENG-123","url":"https://linear.app/..."}. The url is the
one Linear returns, and is null only if Linear sent none.
When the issue is moved to started (below), worktree also reads the issue’s current workflow state (its id, name
and type) and its team’s started states (id, name and position). That is workflow metadata: still no description,
no comments, and nothing from it reaches an agent. The state names are printed.
Requests to Linear are cut off after 15 seconds.
Moving the issue to started
worktree branch --linear ENG-123 can also move the issue to the team’s started state (In Progress, in a default
workflow) once the worktree exists, so the board says the work has begun.
worktree branch --linear ENG-123 --start # move it, whatever linear.autoStart says
worktree branch --linear ENG-123 --no-start # leave it, this run only
worktree config linear.autoStart true # always move it, stop askingWithout a flag, linear.autoStart decides: true moves, false
never does, and unset means you are asked once (“Move this issue to started?”) and the answer is saved to the key.
A non-interactive run, including --json and an agent’s run, moves the issue by default, without saving
anything; pass --no-start or set linear.autoStart false to keep it read-only.
- Only an issue that has not begun moves. One in a backlog or unstarted state goes to the team’s started state
with the lowest position. One that is already started (In Review, say) stays, and so do triage, completed, canceled
and duplicate issues, and a team with no started state. Each is said in words with the state’s name, and with
--jsonstartedistrue(moved, or already started),false(left alone, no started state, or the attempt failed) ornull(not attempted). - A failed move never fails the run. The worktree is still created, and a warning carries Linear’s message.
- It needs a key with the Write permission and access to the issue’s team. A read-only key, or one limited to other teams, is refused by Linear, and the warning says so.
- Nothing happens on a dry run or when an existing worktree is reopened. See
branchfor the order of the run.
Authentication Resolution
Authentication uses one config key, linear.apiKey, read from local git config. In a terminal, branch --linear
offers to run worktree config when it is missing. Without a key after that, and in any non-interactive run, the
command exits with code 2 and missing_value, naming worktree config linear.apiKey <key>, before a worktree
is created.
Suggested Setup
worktree config linear.apiKey <api-key>
worktree config branchPrefix.feature feature/
worktree config branchPrefix.bugfix fix/
worktree config branchPrefix.chore chore/You can also run worktree config and answer yes to the Linear group, or configure only missing values:
worktree config --missing --names linear.apiKey,branchPrefix.feature,branchPrefix.bugfix,branchPrefix.choreAn empty answer to the key prompt keeps the key already stored rather than clearing it.
Getting a Linear API Key
- In Linear, open Settings -> Security & access -> Personal API keys
- Click “New API key” and give it a label
- Copy the key and use it with
worktree config linear.apiKey
Reading an issue needs only a key that can see it. To let worktree move the issue to started,
create the key with the Write permission and access to the teams you work in; without it the move warns and the
worktree is still created.
The key is stored locally in git config and never sent anywhere except to Linear. worktree never prints it:
any lin_api_ key that would reach the output is replaced first. The key is checked the first time --linear
uses it; worktree config refuses a key that is only whitespace but does not check it with Linear.