# 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)

- Skill: `tomevault-io/linear-5` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/linear-5`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/linear-5/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/linear-5

---


# 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`):
```bash
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
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-create-issue.sh` | Create new issue | `--title`, `--description`, `--priority` |
| `linear-list-issues.sh` | List team issues with pagination | `--state`, `--assignee-id`, `--after` |
| `linear-update-issue.sh` | Update issue | `--issue-id`, `--state-id`, `--title` |
| `linear-search.sh` | Search issues with pagination | `--query`, `--after` |

### Comments (Essential for AI Documentation)
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-create-comment.sh` | Add comment to issue | `--issue-id`, `--body` |
| `linear-list-comments.sh` | List issue comments | `--issue-id`, `--limit` |
| `linear-update-comment.sh` | Update comment | `--comment-id`, `--body` |
| `linear-delete-comment.sh` | Delete comment | `--comment-id` |

### Labels (Organization)
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-create-label.sh` | Create team label | `--name`, `--description`, `--color` |
| `linear-list-labels.sh` | List team labels | `--limit` |
| `linear-assign-label.sh` | Add label to issue | `--issue-id`, `--label-id` |
| `linear-remove-label.sh` | Remove label from issue | `--issue-id`, `--label-id` |

### Cycles (Sprint Planning)
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-create-cycle.sh` | Create sprint cycle | `--starts-at`, `--ends-at`, `--name` |
| `linear-list-cycles.sh` | List team cycles | `--include-completed`, `--limit` |
| `linear-update-cycle.sh` | Update cycle | `--cycle-id`, `--completed-at` |

### Projects
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-create-project.sh` | Create project | `--name`, `--description`, `--color` |
| `linear-list-projects.sh` | List team projects | `--limit` |

### Attachments (External Links)
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-create-attachment.sh` | Link external resource | `--issue-id`, `--url`, `--title` |
| `linear-list-attachments.sh` | List issue attachments | `--issue-id` |
| `linear-delete-attachment.sh` | Delete attachment | `--attachment-id` |

### ID Discovery (Essential)
| Script | Purpose | Key Arguments |
|--------|---------|---------------|
| `linear-list-states.sh` | Get workflow state IDs | `--limit` |
| `linear-list-users.sh` | Get team member IDs | `--limit` |
| `linear-get-viewer.sh` | Get authenticated user info | None |

## Common Workflows

### Create Issue from Conversation
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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:**
```json
{
  "success": true,
  "id": "entity-id",
  "identifier": "LFW-123",
  "title": "Entity title",
  "url": "https://linear.app/..."
}
```

**List Operations with Pagination:**
```json
{
  "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
```bash
# 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**
```bash
# ❌ 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**
```bash
# ❌ 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**
```bash
# ❌ 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)

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/dbmcco) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->

