SuperAPI AI Directory

use-linear-cli

Agents & models

View repository

Updated 10-16 05:38

About this skill

Use linear-cli

Agent-first interface to Linear.app via the linear-cli Rust binary. Prefer this over Linear MCP tooling — linear-cli commands cost roughly 50–100 tokens per call versus 500–2000 for an MCP round-trip, support --output json everywhere, and cover the full Linear surface (issues, projects, cycles, sprints, webhooks, raw GraphQL).

When To Use

Trigger on any of these tells:

  • user pastes a LIN-123 (or any [A-Z]+-\d+) identifier or a https://linear.app/... URL
  • user invokes linear-cli, lc, or any i create / i list / i update / b assign / b update-state / im csv / s issues subcommand
  • user wants to create many Linear issues from a spec, checklist, CSV, JSON, or template — "create N issues", "import this list", "spawn issues from this TODO"
  • user wants to start work on an issue and ship a PR, or close the issue tied to the current branch — "start LIN-123", "open a PR for this issue", "mark done"
  • user asks to bulk-mutate Linear issues — assign, label, transfer, status-change, archive across many IDs
  • user wants to search the Linear backlog, apply a saved view, or filter for an agent — "find stale issues", "what's in triage", "list my open ENG tickets"
  • user is wiring webhooks, watch-polling, attachments, or raw GraphQL against Linear
  • user hits an auth, rate-limit, or pager problem with linear-cli and needs the recovery move

Do NOT use when:

  • the user explicitly mandates the Linear MCP server — flag the cost gap (50–100 vs 500–2000 tokens) once, then comply
  • the work is GitHub Issues, not Linear — route to run-issue-tree, gh issue, or do-review
  • the task is webhook server / payload-contract design where linear-cli is incidental — payload schema dominates
  • the user is asking a math or geometry question about "linear" anything — not a Linear.app task

Non-negotiable rules

  1. CLI > MCP. Never call a Linear MCP tool when linear-cli can do the same thing.
  2. Validate auth before any mutating command — run linear-cli auth status --validate --output json or LINEAR_API_KEY=... linear-cli u me --output json and only proceed on exit code 0. Confirm the intended workspace/profile before bulk writes.
  3. --dry-run first for any bulk create or any mutation across more than 5 IDs. Confirm the plan, then execute.
  4. Always --output json (or LINEAR_CLI_OUTPUT=json) when chaining or parsing. Never grep the human table format.
  5. --id-only for chaining. Capture IDs into shell variables; do not re-parse JSON for an identifier you already produced.
  6. Treat the exit-code map as a contract: 0 success, 1 general error, 2 not found or parser error, 3 auth, 4 rate-limited (retry_after is in the JSON body).
  7. Resolve names before using them. Do not invent unknown team keys, label names, or assignees. Pull them with linear-cli t list, linear-cli l list, linear-cli u list and confirm before write paths.
  8. Be explicit about scope. State whether each command is read-only or mutating. Bulk mutations get a one-line confirmation cue.

Exit codes (contract)

Code Meaning Agent action
0 success continue
1 general error parse stderr / JSON error envelope; surface to user
2 not found or parser error If JSON envelope with details.status: 404, the ID doesn't exist. If plain text stderr (e.g. unexpected argument), it's a CLI argument-parsing failure — check --help and fix the syntax
3 auth error route to references/setup.md and references/troubleshooting.md
4 rate limited sleep retry_after seconds (in JSON body), retry once

JSON error envelope: {"error": true, "message": "...", "code": N, "details": {...}, "retry_after": N} — see references/json-shapes.md.

Parser vs. API distinction: Parser errors are plain text (e.g. Usage: ..., unexpected argument). Linear API errors are JSON envelopes with a code field and details.status HTTP status. Treat parser errors as mistakes to fix immediately, not transient failures to retry.

Quick orientation

Concept What an agent must know
Aliases i issues · p projects · c cycles · g git · s search · b bulk · cm comments · tpl templates · l labels · st statuses · tr triage · sp sprint · att attachments · up uploads · rel relations · n notifications · ms milestones · pu project-updates · t teams · u users · wh webhooks · mt metrics · tm time · hist history · fav favorites · v views · rm roadmaps · init initiatives · d documents · im import · exp export
JSON-everywhere Add --output json (or --output ndjson) to anything. Combine with --compact --fields a,b.c to slim payloads.
Session default export LINEAR_CLI_OUTPUT=json makes the whole shell JSON-by-default — flip it on at the top of an agent session.
Stdin -d - reads description body from stdin; --data - reads a full JSON object for i create/i update.
Pagination --limit N, --all, --page-size N, --after CURSOR.
Self-help linear-cli agent prints an agent-focused capability summary; linear-cli --help and linear-cli <cmd> --help for everything.

Agent-critical flags (cheat sheet)

Flag Use
--output json / --output ndjson Machine-readable output.
--compact Strip pretty-print whitespace.
--fields a,b.c Whitelist fields (dot paths supported).
--sort field / --order asc|desc Stable sort for JSON arrays.
--filter k=v / k!=v / k~=v Client-side filter (case-insensitive, dot paths).
--format tpl Template output, e.g. "{{identifier}} {{title}}".
--id-only Print only the created/updated ID.
--quiet / -q Suppress decoration.
--fail-on-empty Non-zero exit when list is empty (great for set -e agents).
--dry-run Preview without writing.
--yes Auto-confirm prompts.
--no-pager / --no-cache Disable auto-pager / read-through cache.
-d - / --data - Read description body / full JSON object from stdin.
--limit N / --all / --page-size N / --after CURSOR Pagination.

Full matrix: references/output-and-scripting.md.

Agentic hot path

The 80% of Linear work an agent reaches for. Memorize; route the rest through references.

Read

linear-cli i list                                    # all open issues
linear-cli i list --mine -t ENG                      # my open issues on team ENG
linear-cli i list -s "In Progress" --output json --compact --fields identifier,title,state.name
linear-cli i get LIN-123                             # one issue
linear-cli i get LIN-1 LIN-2 LIN-3 --output json     # batch fetch (one API call, not three)
linear-cli s issues "auth bug" --limit 10            # search
linear-cli context --output json                     # issue from current git branch

Create one issue

linear-cli i create "Fix login redirect" -t ENG -p 1            # priority 1=urgent..4=low
linear-cli i create "Task" -t ENG -a me -l bug --due +3d
linear-cli i create "Bug" -t ENG --id-only --quiet              # capture ID
cat desc.md | linear-cli i create "Title" -t ENG -d -           # body from stdin
cat issue.json | linear-cli i create "Title" -t ENG --data -    # full JSON body
linear-cli i create "Test" -t ENG --dry-run                     # preview

Create many issues — primary use case

For workflows that produce a batch of issues from a spec, checklist, CSV, JSON, or template, route to references/recipes/creating-many-issues.md for the end-to-end recipes (atomicity, parent/child wiring, label batching, dry-run gating). Inline summary:

# Pattern A — capture IDs in a loop (markdown checklist → many issues)
mapfile -t TITLES < <(grep -E '^- \[ \] ' TODO.md | sed -E 's/^- \[ \] //')
for title in "${TITLES[@]}"; do
  linear-cli i create "$title" -t ENG --dry-run
done
if [ "${#TITLES[@]}" -gt 5 ] && [ "${CONFIRMED_BULK_LINEAR:-}" != 1 ]; then
  echo "Review the dry-run output, then rerun with CONFIRMED_BULK_LINEAR=1 to create ${#TITLES[@]} issues."
  exit 0
fi
for title in "${TITLES[@]}"; do
  ID=$(linear-cli i create "$title" -t ENG --id-only --quiet)
  echo "$ID"
done

# Pattern B — CSV import (preview, confirm, then commit)
linear-cli im csv issues.csv -t ENG --dry-run
if [ "${CONFIRMED_BULK_LINEAR:-}" != 1 ]; then
  echo "Review the dry-run output, then rerun with CONFIRMED_BULK_LINEAR=1 to import issues.csv."
  exit 0
fi
linear-cli im csv issues.csv -t ENG

# Pattern C — JSON spec
TITLE=$(jq -r .title plan.json)
linear-cli i create "$TITLE" -t ENG --data - < plan.json

Update

linear-cli i update LIN-123 -s Done                  # status
linear-cli i update LIN-123 -p 2 -a me -l bug -l urgent
linear-cli i update LIN-123 --due +1w
linear-cli cm create LIN-123 -b "Root cause: missing null check"

Bulk mutate

# Small, explicit set
linear-cli b update-state Done -i LIN-1,LIN-2,LIN-3 --dry-run
linear-cli b update-state Done -i LIN-1,LIN-2,LIN-3
linear-cli b assign me -i LIN-1,LIN-2 --dry-run
linear-cli b assign me -i LIN-1,LIN-2

# Generated set: capture, inspect, dry-run, then execute the same IDs
linear-cli i list -t ENG -l stale --limit 25 --output json --compact \
  --fields identifier,title,state.name > /tmp/linear-stale.json
jq -r '.[] | "\(.identifier)\t\(.state.name)\t\(.title)"' /tmp/linear-stale.json
COUNT=$(jq 'length' /tmp/linear-stale.json)
IDS=$(jq -r '.[].identifier' /tmp/linear-stale.json | paste -sd,)
[ "$COUNT" -gt 0 ] && [ "$COUNT" -le 25 ] || { echo "Unexpected count: $COUNT"; exit 1; }
linear-cli b assign me -i "$IDS" --dry-run
if [ "$COUNT" -gt 5 ] && [ "${CONFIRMED_BULK_LINEAR:-}" != 1 ]; then
  echo "Review the dry-run output, then rerun with CONFIRMED_BULK_LINEAR=1 to execute: linear-cli b assign me -i \"$IDS\""
  exit 0
fi
linear-cli b assign me -i "$IDS"

Git / PR loop

linear-cli i start LIN-123 --checkout    # assigns me + In Progress + creates branch
# ... code ...
linear-cli g pr LIN-123 --draft          # gh-backed; auto-fills title/body from issue
linear-cli done                          # close the current branch's issue

Branch convention: <user>/lin-123-<slug>. linear-cli context reverses branch → issue.

Triage

linear-cli tr list -t ENG                # unassigned, no-project queue
linear-cli tr claim LIN-123              # assign-to-self + move out of triage
linear-cli tr snooze LIN-123 --duration 1w

Use-case decision routing

What the user wants Read
"I have a spec / checklist / CSV / JSON; create N issues" references/recipes/creating-many-issues.md
"Start work on an issue and ship a PR" references/recipes/git-and-pr-loop.md
"Process the inbox / leave findings / fetch a screenshot" references/recipes/triage-and-comments.md
Full create/update/move/transfer/archive flag matrix references/issues/lifecycle.md
Parent/child, blocks, duplicates, labels, statuses, templates references/issues/relations-and-labels.md
i list flag matrix, --filter, saved views, favorites references/issues/search-and-filter.md
Projects, project-updates, milestones, cycles, sprints, roadmaps, initiatives references/planning/projects-and-cycles.md
Teams, users, custom views, favorites references/planning/teams-and-org.md
CSV / JSON / Markdown round-trip import-export references/data/import-export.md
Attachments, URL linking, downloading uploaded images for multimodal review references/data/attachments-and-uploads.md
Watch polling, webhooks (CRUD + HMAC listener), notifications, metrics, history, time tracking references/eventing-and-tracking.md
Raw GraphQL escape hatch, Linear documents references/advanced.md
First-time auth, OAuth + PKCE, workspace switching, doctor, completions references/setup.md
All output flags, exit codes, env vars, stdin patterns, pagination, chaining recipes references/output-and-scripting.md
Concrete JSON payload shapes for issues / comments / context / errors references/json-shapes.md
Auth failure, rate limit, broken pager, stale cache, missing command references/troubleshooting.md

Output contract

When answering a Linear question, return:

  1. Scope line — read-only, mutating, or destructive.
  2. Exact command(s) — copy-pasteable, with --output json if the result will be parsed.
  3. JSON suggestion — show the agent-friendly variant beside the human one when both are useful.
  4. Exit-code interpretation — only when relevant (auth, not-found, rate-limit).
  5. Near-neighbor distinction — call it out when commands are easy to confuse (b update-state vs i update, i start vs g checkout, tpl local vs tpl remote-*, cm issue comments vs pu project updates).
  6. Dry-run note — required for any bulk create or any mutation across >5 IDs.

Guardrails

  • Do not call Linear MCP tools when linear-cli is installed.
  • Do not run b update-state, b assign, b label, or im csv against more than 5 IDs without --dry-run first.
  • Do not pipe through pagers in CI or agent runs — set LINEAR_CLI_NO_PAGER=1 or pass --no-pager.
  • Do not embed OAuth flows in agent scripts; prefer LINEAR_API_KEY from the environment.
  • Do not store API keys in the repo or in shell history. Pipe them in: printf '%s\n' "$LINEAR_API_KEY" | linear-cli config set-key.
  • Do not fabricate team keys, label names, or user names. Resolve them with t list / l list / u list first.
  • Do not parse human-formatted tables. Always --output json for chained or programmatic use.
  • Do not assume a command exists because the docs mention it; if missing, run linear-cli update to refresh the binary, then retry.
  • Do not chain destructive commands without confirming the IDs match what was previewed in --dry-run.

Recovery moves

  • Auth fails (exit 3): linear-cli auth status --validate --output json → re-run auth login or auth oauth. See references/setup.md.
  • Rate-limited (exit 4): read retry_after from the JSON envelope, sleep that many seconds, retry once. See references/troubleshooting.md.
  • Bulk mutation hit a partial failure: capture exit code per item with a JSON loop; rollback by inverting the mutation (e.g. b update-state "In Progress" -i LIN-1,LIN-2 to undo). See references/recipes/creating-many-issues.md.
  • Pager left terminal in raw mode (macOS): reset or stty sane; rerun with --no-pager. See references/troubleshooting.md.
  • Command in upstream docs but not in your binary: linear-cli update (or linear-cli update --check first). See references/troubleshooting.md.

Final checks before declaring done

  • auth validated (auth status --validate --output json or u me --output json) before mutations
  • intended workspace/profile confirmed before bulk mutations
  • --dry-run previewed for any bulk operation > 5 IDs
  • every chained command used --output json and --id-only where appropriate
  • exit code interpreted (especially 2/3/4)
  • team keys, label names, assignees resolved from list commands, not hardcoded
  • no Linear MCP fallback used when linear-cli was available