Skip to content

[feat]: Use Linear's branch name when creating a task from a Linear ticket #1706

@trevorpfsbc

Description

@trevorpfsbc

Feature Summary

Use Linear's generated branch name when creating a task from a Linear issue.


Problem or Use Case

When a task is created from a Linear issue, Emdash generates its own branch name (e.g. emdash/fix-login-bug-abc123) instead of using the one Linear already provides (e.g. eng-4222-fix-login-bug). A lot of teams rely on Linear's branch name format for automatic PR-to-issue linking via Linear's GitHub integration. If the branch name doesn't match, that sync breaks and you lose traceability.


Proposed Solution

When a task is created from a Linear issue, read the branchName field from the Linear API response and use it as the branch name instead of generating one. If no Linear issue is attached, fall back to the existing branchPrefix/generated name behavior.

1. Fetch branchName in LinearService.ts

The Linear GraphQL API returns branchName on the Issue object. Emdash already queries this object in src/main/services/LinearService.ts — just add branchName to the query and include it in the returned payload:

// src/main/services/LinearService.ts

const ISSUE_FIELDS = `
  id
  identifier
  title
  description
  url
  branchName   // ← add this field
  state { name }
  team { id name }
  assignee { name }
  labels { nodes { name } }
`;

The Linear GraphQL query to verify this field:

query GetIssue($id: String!) {
  issue(id: $id) {
    id
    identifier
    title
    branchName   # e.g. "eng-4222-fix-login-bug"
  }
}

→ [Linear API reference](https://developers.linear.app/docs/graphql/working-with-the-graphql-api)

2. Add branchName to the LinearIssueSummary type

// src/renderer/types/linear.ts

export interface LinearIssueSummary {
  identifier: string;
  title: string;
  description?: string | null;
  url?: string | null;
  branchName?: string | null;   // ← add this
  state?: LinearStateRef | null;
  team?: LinearTeamRef | null;
  project?: LinearProjectRef | null;
  assignee?: LinearUserRef | null;
}

3. Use branchName in branchNameGenerator.ts

This is the main change. When a Linear issue is linked and has a branchName, use it directly instead of generating one:

// src/renderer/lib/branchNameGenerator.ts

export function generateBranchName(options: {
  linearIssue?: LinearIssueSummary | null;
  jiraIssue?: JiraIssueSummary | null;
  githubIssue?: GitHubIssueSummary | null;
  branchPrefix?: string;
  taskName?: string;
}): string {
  const { linearIssue, jiraIssue, githubIssue, branchPrefix = 'emdash', taskName } = options;

  // ← NEW: if a Linear issue is linked and has a branchName, use it directly
  if (linearIssue?.branchName) {
    return linearIssue.branchName;  // e.g. "eng-4222-fix-login-bug"
  }

  // existing fallback logic below...
  const prefix = branchPrefix;
  const base = taskName ?? linearIssue?.title ?? jiraIssue?.summary ?? githubIssue?.title ?? 'task';
  const slug = base.toLowerCase().replace(/[^a-z0-9]+/g, '-').slice(0, 50);
  const suffix = Math.random().toString(36).slice(2, 5);
  return `${prefix}/${slug}-${suffix}`;
}

4. Pass branchName through taskCreationService.ts

// src/renderer/lib/taskCreationService.ts

const branchName = generateBranchName({
  linearIssue: options.linearIssue,
  jiraIssue: options.jiraIssue,
  githubIssue: options.githubIssue,
  branchPrefix: projectSettings.branchPrefix,
  taskName: options.taskName,
});

await window.electronAPI.worktreeCreate({
  projectId: options.projectId,
  branchName,
  // ...
});

Alternatives Considered

  • Manually renaming the branch after the worktree is created — works but is tedious, especially when running multiple agents in parallel.
  • Setting repository.branchPrefix to match the team identifier (e.g. eng) — gets the prefix right but still doesn't include the ticket number or match Linear's exact format.

Additional Context

Linear's branchName field follows the format team-identifier-issuenumber-issue-title (e.g. eng-4222-fix-login-bug) and is already returned on the Issue object by the GraphQL API — no extra API calls needed. Since Emdash already fetches issue data from Linear when creating a task (LinearService.tslinearIpc.tstaskCreationService.ts), this field is available at no cost.

The troubleshooting docs confirm the current branch pattern (emdash/task-name-abc), and a recent PR ([#1639](#1639) — "Fix: apply branch prefix to remote worktree creation") shows this is an actively maintained code path.

Files to change:

  • src/main/services/LinearService.ts — add branchName to GraphQL query
  • src/renderer/types/linear.ts — add branchName to LinearIssueSummary
  • src/renderer/lib/branchNameGenerator.ts — use linearIssue.branchName when present
  • src/renderer/lib/taskCreationService.ts — pass the resolved branch name through to worktreeCreate

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions