linear

Use when managing Linear issues, creating tasks from conversations, tracking work items, or querying project status - provides bash scripts to interact with Linear's GraphQL API without writing queries directly (project, gitignored)

$ Instalar

git clone https://github.com/dbmcco/claude-agent-toolkit /tmp/claude-agent-toolkit && cp -r /tmp/claude-agent-toolkit/skills/linear ~/.claude/skills/claude-agent-toolkit

// tip: Run this command in your terminal to install the skill


name: linear description: Use when managing Linear issues, creating tasks from conversations, tracking work items, or querying project status - provides bash scripts to interact with Linear's GraphQL API without writing queries directly (project, gitignored)

Linear Integration

Overview

Comprehensive Linear API integration through simple bash scripts. All scripts handle GraphQL API calls internally - you just provide arguments. Covers the full API: issues, comments, labels, cycles, projects, attachments, and team management.

Core principle: Agents manage Linear without learning GraphQL syntax or API details.

When to Use

  • Creating issues from conversation context
  • Documenting implementation progress via comments
  • Organizing work with labels and cycles
  • Tracking projects and sprint planning
  • Linking external resources (PRs, docs, designs)
  • Querying team structure and workflow states

Environment Setup

Required variables (set in /experiments/skills/.env):

LINEAR_API_KEY=lin_api_xxx
LINEAR_TEAM_ID=xxx-xxx-xxx
LINEAR_TEAM_KEY=LFW
LINEAR_ORG_URL=lightforgeworks

Scripts automatically source the .env file from parent directory.

Quick Reference

Issue Management

ScriptPurposeKey Arguments
linear-create-issue.shCreate new issue--title, --description, --priority
linear-list-issues.shList team issues with pagination--state, --assignee-id, --after
linear-update-issue.shUpdate issue--issue-id, --state-id, --title
linear-search.shSearch issues with pagination--query, --after

Comments (Essential for AI Documentation)

ScriptPurposeKey Arguments
linear-create-comment.shAdd comment to issue--issue-id, --body
linear-list-comments.shList issue comments--issue-id, --limit
linear-update-comment.shUpdate comment--comment-id, --body
linear-delete-comment.shDelete comment--comment-id

Labels (Organization)

ScriptPurposeKey Arguments
linear-create-label.shCreate team label--name, --description, --color
linear-list-labels.shList team labels--limit
linear-assign-label.shAdd label to issue--issue-id, --label-id
linear-remove-label.shRemove label from issue--issue-id, --label-id

Cycles (Sprint Planning)

ScriptPurposeKey Arguments
linear-create-cycle.shCreate sprint cycle--starts-at, --ends-at, --name
linear-list-cycles.shList team cycles--include-completed, --limit
linear-update-cycle.shUpdate cycle--cycle-id, --completed-at

Projects

ScriptPurposeKey Arguments
linear-create-project.shCreate project--name, --description, --color
linear-list-projects.shList team projects--limit

Attachments (External Links)

ScriptPurposeKey Arguments
linear-create-attachment.shLink external resource--issue-id, --url, --title
linear-list-attachments.shList issue attachments--issue-id
linear-delete-attachment.shDelete attachment--attachment-id

ID Discovery (Essential)

ScriptPurposeKey Arguments
linear-list-states.shGet workflow state IDs--limit
linear-list-users.shGet team member IDs--limit
linear-get-viewer.shGet authenticated user infoNone

Common Workflows

Create Issue from Conversation

# Create issue with conversation context
scripts/linear-create-issue.sh \
  --title "Implement user authentication" \
  --description "Based on discussion: Need OAuth2 integration with Google and GitHub providers" \
  --priority 2

Document Implementation Progress

# Add progress comment to issue
scripts/linear-create-comment.sh \
  --issue-id "abc-123" \
  --body "Implemented OAuth2 flow. Tests passing. Ready for review."

# Link PR as attachment
scripts/linear-create-attachment.sh \
  --issue-id "abc-123" \
  --url "https://github.com/org/repo/pull/456" \
  --title "PR: OAuth2 Implementation"

Organize Work

# Get label IDs
scripts/linear-list-labels.sh

# Assign labels to categorize
scripts/linear-assign-label.sh \
  --issue-id "abc-123" \
  --label-id "label-backend"

scripts/linear-assign-label.sh \
  --issue-id "abc-123" \
  --label-id "label-security"

Update Issue State

# First get state IDs
scripts/linear-list-states.sh

# Then update to "In Progress"
scripts/linear-update-issue.sh \
  --issue-id "abc-123" \
  --state-id "state-in-progress-id"

Sprint Planning

# Create cycle
scripts/linear-create-cycle.sh \
  --name "Sprint 42" \
  --starts-at "2025-11-01" \
  --ends-at "2025-11-14" \
  --description "Q4 authentication features"

# Assign issue to cycle
scripts/linear-update-issue.sh \
  --issue-id "abc-123" \
  --cycle-id "cycle-id-from-above"

Pagination for Large Teams

# Get first page
RESULT=$(scripts/linear-list-issues.sh --state "Backlog" --limit 50)

# Check if more pages
HAS_NEXT=$(echo "$RESULT" | jq -r '.pageInfo.hasNextPage')

if [ "$HAS_NEXT" = "true" ]; then
  CURSOR=$(echo "$RESULT" | jq -r '.pageInfo.endCursor')

  # Get next page
  scripts/linear-list-issues.sh --state "Backlog" --limit 50 --after "$CURSOR"
fi

Output Format

All scripts return JSON with relevant data:

Create/Update Operations:

{
  "success": true,
  "id": "entity-id",
  "identifier": "LFW-123",
  "title": "Entity title",
  "url": "https://linear.app/..."
}

List Operations with Pagination:

{
  "issues": [...],
  "pageInfo": {
    "hasNextPage": true,
    "endCursor": "cursor-string-for-next-page"
  }
}

Common Patterns

AI Agent Workflow

  1. Create issue from user conversation
  2. Add comment documenting implementation approach
  3. Update state to "In Progress"
  4. Add attachment linking to PR/branch
  5. Add comment with completion notes
  6. Update state to "Done"

ID Discovery Pattern

# Always get IDs first before operations
STATES=$(scripts/linear-list-states.sh)
IN_PROGRESS_ID=$(echo "$STATES" | jq -r '.[] | select(.name=="In Progress") | .id')

USERS=$(scripts/linear-list-users.sh)
MY_ID=$(echo "$USERS" | jq -r '.[] | select(.email=="me@example.com") | .id')

# Then use in operations
scripts/linear-update-issue.sh \
  --issue-id "abc-123" \
  --state-id "$IN_PROGRESS_ID" \
  --assignee-id "$MY_ID"

Common Mistakes

Missing environment variables

  • Scripts check for LINEAR_API_KEY and LINEAR_TEAM_ID
  • Error message shows which variables are missing

Using Linear CLI syntax

  • ❌ Don't: linear issue create "Title"
  • ✅ Do: linear-create-issue.sh --title "Title"

Forgetting to get IDs first

  • State IDs, project IDs, user IDs, label IDs must be fetched
  • Use list scripts to discover IDs before operations

Not handling pagination

  • Teams with 100+ issues need pagination
  • Always check pageInfo.hasNextPage in list operations
  • Use --after parameter with endCursor for next page

Not documenting work

  • Comments are essential for AI agents to track progress
  • Always add comments when making significant changes
  • Link related resources (PRs, docs) via attachments

Anti-Patterns

Creating issues without context

# ❌ Bad: Minimal context
scripts/linear-create-issue.sh --title "Fix bug"

# ✅ Good: Rich context from conversation
scripts/linear-create-issue.sh \
  --title "Fix authentication timeout on mobile Safari" \
  --description "Users report auth timeout after 30s on iOS Safari. Need to increase token TTL and add retry logic." \
  --priority 1

Silent updates

# ❌ Bad: Update state without documentation
scripts/linear-update-issue.sh --issue-id "abc-123" --state-id "done"

# ✅ Good: Document completion
scripts/linear-create-comment.sh \
  --issue-id "abc-123" \
  --body "Implemented fix. Increased token TTL to 120s and added exponential backoff. All tests passing."

scripts/linear-update-issue.sh --issue-id "abc-123" --state-id "done"

Ignoring pagination

# ❌ Bad: Only get first 50 issues
scripts/linear-list-issues.sh --limit 50

# ✅ Good: Handle all pages
while true; do
  RESULT=$(scripts/linear-list-issues.sh --limit 50 ${CURSOR:+--after "$CURSOR"})
  echo "$RESULT" | jq -r '.issues[]'

  HAS_NEXT=$(echo "$RESULT" | jq -r '.pageInfo.hasNextPage')
  [ "$HAS_NEXT" = "false" ] && break

  CURSOR=$(echo "$RESULT" | jq -r '.pageInfo.endCursor')
done

Script Location

All scripts in: /Users/braydon/projects/experiments/skills/linear/scripts/

Can be called from any directory - they auto-source the parent .env file.

API Coverage

This skill covers the full Linear GraphQL API:

  • ✅ Issues (CRUD, search, filtering)
  • ✅ Comments (CRUD)
  • ✅ Labels (CRUD, assignment)
  • ✅ Cycles (CRUD, sprint management)
  • ✅ Projects (CRUD)
  • ✅ Attachments (CRUD, external linking)
  • ✅ Workflow States (query)
  • ✅ Team Members (query)
  • ✅ Authenticated User (query)
  • ✅ Pagination (cursor-based)