This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Claude Code skill for managing Linear issues, projects, and teams. It provides high-level TypeScript operations, a label taxonomy system for consistent categorization, and utilities for SDK automation.
# Run setup check (validates LINEAR_API_KEY and dependencies)
npm run setup
# High-level operations CLI
npm run ops -- <command> [args]
npm run ops -- help # Show all commands
npm run ops -- create-issue "Project" "Title" "Desc"
npm run ops -- create-sub-issue ENG-100 "Title"
npm run ops -- labels taxonomy # Show label taxonomy
npm run ops -- labels validate "feature,security"
# Run GraphQL query
npm run query -- "query { viewer { name } }"
# Test Linear connection
npm run test-connectionlinear-claude-skill/
├── SKILL.md # Main skill instructions (loaded by Claude Code)
├── api.md # GraphQL API reference
├── sdk.md # SDK automation patterns
├── sync.md # Bulk sync patterns
├── docs/
│ └── labels.md # Label taxonomy documentation
├── hooks/
│ └── post-edit.sh # Auto-sync hook
├── scripts/
│ ├── run.sh # Shared runner (dist/ with tsx fallback)
│ ├── linear-ops.ts # CLI for high-level operations (main entry point)
│ ├── query.ts # GraphQL query runner
│ ├── setup.ts # Configuration validator
│ ├── sync.ts # Bulk sync operations
│ ├── linear-api.mjs # Direct API wrapper
│ └── lib/ # Shared utilities (imported by scripts)
│ ├── index.ts # Re-exports all utilities
│ ├── labels.ts # Label management (CRUD, validation)
│ ├── taxonomy*.ts # Label taxonomy system (types, data, validation)
│ ├── agent-selection.ts # Agent routing based on labels
│ ├── initiative.ts # Initiative linking
│ ├── lin-cli.ts # Optional lin CLI integration (tryLin, detection, typed wrappers)
│ ├── project-template.ts # Project creation with verification
│ └── verify.ts # Post-creation verification
linear-ops.ts — Main CLI entry point. Dispatches to command handlers for issues, projects, initiatives, and labels. All commands follow the pattern:
const commands: Record<string, (...args: string[]) => Promise<void>> = { ... }lib/index.ts — Central export hub. All scripts import from ./lib not individual files.
Label Taxonomy System — Four files work together:
taxonomy.ts: TypeScript interfaces (DomainLabel, TypeLabel, ScopeLabel, AgentId)taxonomy-data.ts: Label definitions with colors, descriptions, agent mappingstaxonomy-validation.ts: Validation rules and keyword-based suggestionagent-selection.ts: Routes issues to agents based on domain labels
lin-cli.ts — Optional integration with the lin Rust CLI binary. Provides
isLinCliAvailable() detection (cached) and tryLin() — the single abstraction
used by command handlers for silent fast-path with SDK fallback. Includes typed
wrappers, circuit-breaker after 3 failures, and LINEAR_USE_LIN=0 kill switch.
project-template.ts — Enforces the 6-step project creation workflow:
- Create project with description
- Link to initiative (mandatory)
- Set content via projectUpdate mutation
- Ensure labels exist
- Create issues with labels
- Run verification
All TypeScript entry points in scripts/ are pre-compiled to dist/ using esbuild for faster CLI startup (eliminates tsx runtime compilation overhead).
scripts/build.mjs auto-discovers every scripts/*.ts file and bundles each one to dist/*.js. External dependencies (@linear/sdk) are kept external — not inlined into the bundle.
__BUNDLED__ build-time define: The linear-ops.ts entry point declares __BUNDLED__ as a global. At build time, esbuild replaces all occurrences with true. This lets code detect whether it is running from a pre-built bundle or via tsx at development time.
Shared runner (scripts/run.sh): All npm scripts delegate to a single shell script that checks for the pre-built dist/*.js file first, falling back to npx tsx if dist is missing:
"ops": "sh scripts/run.sh linear-ops"
Key commands:
npm run build— Run esbuild (also runstypecheckviaprebuild)npm test— Run smoke tests that validate build outputnpx tsc --noEmit— Type-check without emitting files
LINEAR_API_KEY # Required - Linear API key (lin_api_...)
LINEAR_DEFAULT_INITIATIVE_ID # Optional - Default initiative for createProjectWithDefaults()
LINEAR_USE_LIN # Optional - Set to 0 to disable lin CLI fast-path
When creating issues, apply labels in this order:
- Type (exactly one):
feature,bug,refactor,chore,spike - Domain (1-2):
security,backend,frontend,testing,infrastructure, etc. - Scope (0-2 if applicable):
blocked,breaking-change,tech-debt, etc.
Use npm run ops -- labels validate "..." to check label combinations.
- Use
@linear/sdkfor typed operations (imported asLinearClient) - GraphQL mutations via
fetch('https://api.linear.app/graphql', ...)for operations not in SDK - Content vs Description:
descriptionis 255 chars for list views;contentis unlimited for detail panel - Project status requires UUID lookup:
query { projectStatuses { nodes { id name } } } - Initiative linking uses
initiativeToProjectCreatemutation (not SDK method)
The skill is designed to work with Linear's official MCP server at mcp.linear.app. Helper scripts provide fallbacks for unreliable MCP operations (status updates, comments).