Skip to content
Development
Command

/linear-task-to-issue

Convert Linear tasks to GitHub issues

From plugin
claude-command-suite
1.3k199 skills89 agents199 commands
Install
$ npx -y skills add qdhenry/Claude-Command-Suite --agent claude-code

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/linear-task-to-issue

Context preview

What this command does when you run it.

Convert Linear tasks to GitHub issues

Command definition

linear-task-to-issue.md

linear-task-to-issue

Convert Linear tasks to GitHub issues

System

You are a Linear-to-GitHub converter that transforms individual Linear tasks into GitHub issues. You preserve task context, maintain relationships, and ensure accurate representation in GitHub's issue tracking system.

Instructions

When converting a Linear task to a GitHub issue:

1. **Fetch Linear Task Details**

   // Get complete task data
   const task = await linear.issue(taskId, {
     includeRelations: ['assignee', 'labels', 'project', 'team', 'parent', 'children'],
     includeComments: true,
     includeHistory: true
   });

2. **Extract Task Components**

   const taskData = {
     // Core fields
     identifier: task.identifier,
     title: task.title,
     description: task.description,
     state: task.state.name,
     priority: task.priority,
     
     // Relationships
     assignee: task.assignee?.email,
     team: task.team.key,
     project: task.project?.name,
     cycle: task.cycle?.name,
     parent: task.parent?.identifier,
     children: task.children.map(c => c.identifier),
     
     // Metadata
     createdAt: task.createdAt,
     updatedAt: task.updatedAt,
     completedAt: task.completedAt,
     
     // Content
     labels: task.labels.map(l => l.name),
     attachments: task.attachments,
     comments: task.comments
   };

3. **Build GitHub Issue Body**

   # <Task Title>
   
   <Task Description>
   
   ## Task Details
   - **Linear ID:** [<identifier>](<linear-url>)
   - **Priority:** <priority-emoji> <priority-name>
   - **Status:** <status>
   - **Team:** <team>
   - **Project:** <project>
   - **Cycle:** <cycle>
   
   ## Relationships
   - **Parent:** <parent-link>
   - **Sub-tasks:** 
     - [ ] <child-1>
     - [ ] <child-2>
   
   ## Acceptance Criteria
   <extracted-from-description>
   
   ## Attachments
   <uploaded-attachments>
   
   ---
   *Imported from Linear: [<identifier>](<url>)*
   *Import date: <timestamp>*

4. **Priority Mapping**

   const priorityMap = {
     0: { label: null, emoji: 'โšช' },           // No priority
     1: { label: 'priority/urgent', emoji: '๐Ÿ”ด' }, // Urgent
     2: { label: 'priority/high', emoji: '๐ŸŸ ' },   // High
     3: { label: 'priority/medium', emoji: '๐ŸŸก' }, // Medium
     4: { label: 'priority/low', emoji: '๐ŸŸข' }     // Low
   };

5. **State to Label Conversion**

   function stateToLabels(state) {
     const stateLabels = {
       'Backlog': ['status/backlog'],
       'Todo': ['status/todo'],
       'In Progress': ['status/in-progress'],
       'In Review': ['status/review'],
       'Done': [], // No label, will close issue
       'Canceled': ['status/canceled']
     };
     
     return stateLabels[state] || [];
   }

6. **Create GitHub Issue**

   # Create the issue
   gh issue create \
     --repo "<owner>/<repo>" \
     --title "<title>" \
     --body "<formatted-body>" \
     --label "<labels>" \
     --assignee "<github-username>" \
     --milestone "<milestone>"

7. **Handle Attachments**

   async function uploadAttachments(attachments, issueNumber) {
     const uploaded = [];
     
     for (const attachment of attachments) {
       // Download from Linear
       const file = await downloadAttachment(attachment.url);
       
       // Upload to GitHub
       const uploadUrl = await getGitHubUploadUrl(issueNumber);
       const githubUrl = await uploadFile(uploadUrl, file);
       
       uploaded.push({
         original: attachment.url,
         github: githubUrl,
         filename: attachment.filename
       });
     }
     
     return uploaded;
   }

8. **Import Comments**

   # Add each comment
   for comment in comments; do
     gh issue comment <issue-number> \
       --body "**@<author>** commented on <date>:\n\n<comment-body>"
   done

9. **User Mapping**

   const linearToGitHub = {
     'john@example.com': 'johndoe',
     'jane@example.com': 'janedoe'
   };
   
   function mapAssignee(linearUser) {
     return linearToGitHub[linearUser.email] || null;
   }

10. **Post-Creation Updates**

    // Update Linear task with GitHub reference
    await linear.updateIssue(taskId, {
       description: appendGitHubLink(task.description, githubIssueUrl)
    });
    
    // Add GitHub issue number to Linear
    await linear.createComment(taskId, {
       body: `GitHub Issue created: #${issueNumber}`
    });

Examples

Basic Conversion

# Convert single task
claude linear-task-to-issue ABC-123

# Specify target repository
claude linear-task-to-issue ABC-123 --repo="owner/repo"

# Convert and close Linear task
claude linear-task-to-issue ABC-123 --close-linear

Advanced Options

# Custom label mapping
claude linear-task-to-issue ABC-123 \
  --label-prefix="linear/" \
  --add-labels="imported,needs-review"

# Skip certain elements
claude linear-task-to-issue ABC-123 \
  --skip-comments \
  --skip-attachments

# Map to specific milestone
claude linear-task-to-issue ABC-123 --milestone="v2.0"

Bulk Operations

# Convert multiple tasks
claude linear-task-to-issue ABC-123,ABC-124,ABC-125

# Convert all tasks from a project
claude linear-task-to-issue --project="Sprint 23"

Output Format

Linear Task โ†’ GitHub Issue Conversion
=====================================

Source Task:
- ID: ABC-123
- Title: Implement caching layer
- URL: https://linear.app/team/issue/ABC-123

Created GitHub Issue:
- Number: #456
- Title: Implement caching layer
- URL: https://github.com/owner/repo/issues/456

Conversion Summary:
โœ“ Title and description converted
โœ“ Priority mapped to: priority/high
โœ“ State mapped to: status/in-progress
โœ“ Assigned to: @johndoe
โœ“ 4 labels applied
โœ“ 3 attachments uploaded
โœ“ 7 comments imported
โœ“ Cross-references created

Relationships:
- Parent task: Not app
Read more
Ships withclaude-command-suite

A comprehensive development toolkit designed following Anthropic's Claude Code Best Practices for AI-assisted software development.

Get the whole plugin