/linear-task-to-issue
Convert Linear tasks to GitHub issues
$ npx -y skills add qdhenry/Claude-Command-Suite --agent claude-codeHow 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.mdlinear-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>"
done9. **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
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>"
done9. **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
A comprehensive development toolkit designed following Anthropic's Claude Code Best Practices for AI-assisted software development.
Repo: qdhenry/Claude-Command-Suite
Other commands on claude-command-suite.
- /boundary-bbcr-fallback
Execute automatic BBCR (Collapse-Rebirth Correction) when knowledge boundaries are exceeded or reasoning fails.
Open command - /boundary-detect
Analyze semantic position relative to knowledge boundaries to prevent hallucination and identify uncertainty zones.
Open command - /boundary-heatmap
Generate a visual heatmap of knowledge boundaries showing safe zones, risk areas, and semantic coverage.
Open command - /boundary-risk-assess
Evaluate the current risk level and provide detailed analysis of potential hallucination or reasoning failure.
Open command - /boundary-safe-bridge
Find and construct semantic bridges to safely navigate from current position to target concept without crossing dangerous boundaries.
Open command - /optimize-prompt
Takes an input prompt and returns ONLY a token-optimized version that preserves meaning while minimizing token count. Based on LLM tokenization principles: common words tokenize more efficiently, unusual words break into more tokens, and conciseness reduces cost.
Open command

