Note: This is a fork of dorkitude/linctl with additional features and enhancements maintained by Mike Beaumier.
A comprehensive command-line interface for Linear's API, built with agents in mind (but nice for humans too).
- π Authentication: Personal API Key support
- π Issue Management: Create, list, view, update, assign, and manage issues with full details
- Sub-issue hierarchy with parent/child relationships
- Issue relations: blocks, blocked-by, related, duplicate
- Git branch integration showing linked branches
- Cycle (sprint) and project associations
- Attachments and recent comments preview
- Due dates, snoozed status, and completion tracking
- Full-text search via
linctl issue search
- π₯ Team Management: View teams, get team details, and list team members
- π Project Tracking: Comprehensive project information
- Progress visualization with issue statistics
- Team and member associations
- Initiative hierarchy
- Recent issues preview
- Timeline tracking (created, updated, completed dates)
- π€ User Management: List all users, view user details, and current user info
- π¬ Comments: List and create comments on issues with time-aware formatting
- π Attachments: View file uploads and attachments on issues
- π Webhooks: Configure and manage webhooks
- π¨ Multiple Output Formats: Table, plaintext, and JSON output
- β‘ Performance: Fast and lightweight CLI tool
- π Flexible Sorting: Sort lists by Linear's default order, creation date, or update date
- π Time-based Filtering: Filter lists by creation date with intuitive time expressions
- π Built-in Documentation: Access full documentation with
linctl docs - π§ͺ Smoke Testing: Automated smoke tests for all read-only commands
git clone https://github.com/delphos-mike/linctl.git
cd linctl
make deps # Install dependencies
make build # Build the binary
make install # Install to /usr/local/bin (requires sudo)
linctl docs # Render the README.mdgit clone https://github.com/delphos-mike/linctl.git
cd linctl
make deps # Install dependencies
go run main.go # Run directly without building
make dev # Or build and run in development mode
make test # Run all tests
make lint # Run linter
make fmt # Format code
linctl docs # Render the README.mdFor the original version without fork-specific features, see dorkitude/linctl.
By default, issue list, issue search, and project list commands only show items created in the last 6 months!
This improves performance and prevents overwhelming data loads. To see older items:
- Use
--newer-than 1_year_agofor items from the last year - Use
--newer-than all_timeto see ALL items ever created - See the Time-based Filtering section for details
By default, issue list and issue search also filter out canceled and completed items. To see all items, use the --include-completed flag.
- Need archived matches? Add
--include-archivedwhen usingissue search.
IMPORTANT Agents like Claude Code, Cursor, and Gemini should use the
--jsonflag on all read operations.
# Interactive authentication
linctl auth
# Check authentication status
linctl auth status
# Show current user
linctl whoami
# View full documentation
linctl docs | less# List all issues
linctl issue list
# List issues assigned to you
linctl issue list --assignee me
# List issues in a specific state
linctl issue list --state "In Progress"
# List issues sorted by update date
linctl issue list --sort updated
# Search issues using Linear's full-text index (shares the same filters as list)
linctl issue search "login bug" --team ENG
linctl issue search "customer:" --include-completed --include-archived
# List recent issues (last 2 weeks instead of default 6 months)
linctl issue list --newer-than 2_weeks_ago
# List ALL issues ever created (override 6-month default)
linctl issue list --newer-than all_time
# List today's issues
linctl issue list --newer-than 1_day_ago
# Get issue details (now includes git branch, cycle, project, attachments, and comments)
linctl issue get LIN-123
# Create a new issue
linctl issue create --title "Bug fix" --team ENG
# Assign issue to yourself
linctl issue assign LIN-123
# Update issue fields
linctl issue update LIN-123 --title "New title"
linctl issue update LIN-123 --description "Updated description"
linctl issue update LIN-123 --assignee john.doe@company.com
linctl issue update LIN-123 --assignee me # Assign to yourself
linctl issue update LIN-123 --assignee unassigned # Remove assignee
linctl issue update LIN-123 --state "In Progress"
linctl issue update LIN-123 --priority 1 # 0=None, 1=Urgent, 2=High, 3=Normal, 4=Low
linctl issue update LIN-123 --due-date "2024-12-31"
linctl issue update LIN-123 --due-date "" # Remove due date
# Update multiple fields at once
linctl issue update LIN-123 --title "Critical Bug" --assignee me --priority 1
# Manage issue relations (dependencies)
linctl issue relate LIN-123 --blocks LIN-456 # Mark LIN-123 as blocking LIN-456
linctl issue relate LIN-123 --blocked-by LIN-456 # Mark LIN-123 as blocked by LIN-456
linctl issue relate LIN-123 --related LIN-456 # Create a general relation
linctl issue relate LIN-123 --duplicate LIN-456 # Mark as duplicate
# Remove issue relations
linctl issue unrelate LIN-123 --blocks LIN-456 # Remove blocking relation# List all projects (shows IDs)
linctl project list
# Filter projects by team
linctl project list --team ENG
# List projects created in the last month (instead of default 6 months)
linctl project list --newer-than 1_month_ago
# List ALL projects regardless of age
linctl project list --newer-than all_time
# Get project details (use ID from list command)
linctl project get 65a77a62-ec5e-491e-b1d9-84aebee01b33# List all teams
linctl team list
# Get team details
linctl team get ENG
# List team members
linctl team members ENG# List all users
linctl user list
# Show only active users
linctl user list --active
# Get user details by email
linctl user get john@example.com
# Show your own profile
linctl user me# List comments on an issue
linctl comment list LIN-123
# Add a comment to an issue
linctl comment create LIN-123 --body "Fixed the authentication bug"--plaintext, -p: Plain text output (non-interactive)--json, -j: JSON output for scripting--help, -h: Show help--version, -v: Show version
linctl auth # Interactive authentication
linctl auth login # Same as above
linctl auth status # Check authentication status
linctl auth logout # Clear stored credentials
linctl whoami # Show current user# List issues with filters
linctl issue list [flags]
linctl issue ls [flags] # Short alias
# Flags:
-a, --assignee string Filter by assignee (email or 'me')
-c, --include-completed Include completed and canceled issues
-s, --state string Filter by state name
-t, --team string Filter by team key
-r, --priority int Filter by priority (0-4, default: -1)
-l, --limit int Maximum results (default 50)
-o, --sort string Sort order: linear (default), created, updated
-n, --newer-than string Show items created after this time (default: 6_months_ago, use 'all_time' for no filter)
# Get issue details (shows parent and sub-issues)
linctl issue get <issue-id>
linctl issue show <issue-id> # Alias
# Create issue
linctl issue create [flags]
linctl issue new [flags] # Alias
# Flags:
--title string Issue title (required)
-d, --description string Issue description
-t, --team string Team key (required)
--priority int Priority 0-4 (default 3)
-m, --assign-me Assign to yourself
# Assign issue to yourself
linctl issue assign <issue-id>
# Update issue
linctl issue update <issue-id> [flags]
linctl issue edit <issue-id> [flags] # Alias
# Flags:
--title string New title
-d, --description string New description
-a, --assignee string Assignee (email, name, 'me', or 'unassigned')
-s, --state string State name (e.g., 'Todo', 'In Progress', 'Done')
--priority int Priority (0=None, 1=Urgent, 2=High, 3=Normal, 4=Low)
--due-date string Due date (YYYY-MM-DD format, or empty to remove)
# Archive issue (coming soon)
linctl issue archive <issue-id># List all teams with issue counts
linctl team list
linctl team ls # Alias
# Flags:
-l, --limit int Maximum results (default 50)
-o, --sort string Sort order: linear (default), created, updated
# Get team details
linctl team get <team-key>
linctl team show <team-key> # Alias
# Examples:
linctl team get ENG # Shows Engineering team details
linctl team get DESIGN # Shows Design team details
# List team members with roles and status
linctl team members <team-key>
# Examples:
linctl team members ENG # Lists all Engineering team members# List projects
linctl project list [flags]
linctl project ls [flags] # Alias
# Flags:
-t, --team string Filter by team key
-s, --state string Filter by state (planned, started, paused, completed, canceled)
-l, --limit int Maximum results (default 50)
-o, --sort string Sort order: linear (default), created, updated
-n, --newer-than string Show items created after this time (default: 6_months_ago)
-c, --include-completed Include completed and canceled projects
# Get project details
linctl project get <project-id>
linctl project show <project-id> # Alias
# Create project (coming soon)
linctl project create [flags]# List all users in workspace
linctl user list [flags]
linctl user ls [flags] # Alias
# Flags:
-a, --active Show only active users
-l, --limit int Maximum results (default 50)
-o, --sort string Sort order: linear (default), created, updated
# Examples:
linctl user list # List all users
linctl user list --active # List only active users
# Get user details by email
linctl user get <email>
linctl user show <email> # Alias
# Examples:
linctl user get john@example.com
linctl user get jane.doe@company.com
# Show current authenticated user
linctl user me # Shows your profile with admin status# List all comments for an issue
linctl comment list <issue-id> [flags]
linctl comment ls <issue-id> [flags] # Alias
# Flags:
-l, --limit int Maximum results (default 50)
-o, --sort string Sort order: linear (default), created, updated
# Examples:
linctl comment list LIN-123 # Shows all comments with timestamps
linctl comment list LIN-456 -l 10 # Show latest 10 comments
# Add comment to issue
linctl comment create <issue-id> --body "Comment text"
linctl comment add <issue-id> -b "Comment text" # Alias
linctl comment new <issue-id> -b "Comment text" # Alias
# Examples:
linctl comment create LIN-123 --body "I've started working on this"
linctl comment add LIN-123 -b "Fixed in commit abc123"
linctl comment create LIN-456 --body "@john please review this PR"linctl issue listID Title State Assignee Team Priority
LIN-123 Fix authentication In Progress john@co.com ENG High
LIN-124 Update documentation Done jane@co.com DOC Normal
linctl issue list --plaintext# Issues
## BUG: Fix login button alignment
- **ID**: FAK-123
- **State**: In Progress
- **Assignee**: Jane Doe
- **Team**: WEB
- **Created**: 2025-07-12
- **URL**: https://linear.app/example/issue/FAK-123/bug-fix-login-button-alignment
- **Description**: The login button on the main page is misaligned on mobile devices.
Steps to reproduce:
1. Open the website on a mobile browser.
2. Navigate to the login page.
3. Observe the button alignment.
## FEAT: Add dark mode support
- **ID**: FAK-124
- **State**: Todo
- **Assignee**: John Smith
- **Team**: APP
- **Created**: 2025-07-11
- **URL**: https://linear.app/example/issue/FAK-124/feat-add-dark-mode-support
- **Description**: Implement a dark mode theme for the entire application to improve user experience in low-light environments.
linctl issue list --json[
{
"id": "LIN-123",
"title": "Fix authentication",
"state": "In Progress",
"assignee": "john@co.com",
"team": "ENG",
"priority": "High"
}
]Configuration is stored in ~/.linctl.yaml:
# Default output format
output: table
# Default pagination limit
limit: 50
# API settings
api:
timeout: 30s
retries: 3Authentication credentials are stored securely in ~/.linctl-auth.json.
- Go to Linear Settings > API
- Create a new Personal API Key
- Run
linctl authand paste your key
The --newer-than (or -n) flag is available on issue list and project list commands:
# Default behavior (last 6 months)
linctl issue list
# Show items from a specific time period
linctl issue list --newer-than 2_weeks_ago
linctl project list --newer-than 1_month_ago
# Show ALL items regardless of age
linctl issue list --newer-than all_time-
Relative time expressions:
N_units_ago- Units:
minutes,hours,days,weeks,months,years - Examples:
30_minutes_ago,2_hours_ago,3_days_ago,1_week_ago,6_months_ago
- Units:
-
Special values:
all_time- Shows all items without any date filter- ISO dates -
2025-07-01or2025-07-01T15:30:00Z
-
Default value:
6_months_ago(when flag is not specified)
| Time Expression | Description | Example Command |
|---|---|---|
| (no flag) | Last 6 months (default) | linctl issue list |
1_day_ago |
Last 24 hours | linctl issue list --newer-than 1_day_ago |
1_week_ago |
Last 7 days | linctl issue list --newer-than 1_week_ago |
2_weeks_ago |
Last 14 days | linctl issue list --newer-than 2_weeks_ago |
1_month_ago |
Last month | linctl issue list --newer-than 1_month_ago |
3_months_ago |
Last quarter | linctl issue list --newer-than 3_months_ago |
6_months_ago |
Last 6 months | linctl issue list --newer-than 6_months_ago |
1_year_ago |
Last year | linctl issue list --newer-than 1_year_ago |
all_time |
No date filter | linctl issue list --newer-than all_time |
2025-07-01 |
Since specific date | linctl issue list --newer-than 2025-07-01 |
# Recent activity - issues from last week
linctl issue list --newer-than 1_week_ago
# Sprint planning - issues from current month
linctl issue list --newer-than 1_month_ago --state "Todo"
# Quarterly review - all projects from last 3 months
linctl project list --newer-than 3_months_ago
# Historical analysis - ALL issues ever created
linctl issue list --newer-than all_time --sort created
# Today's issues
linctl issue list --newer-than 1_day_ago
# Combine with other filters
linctl issue list --newer-than 2_weeks_ago --assignee me --sort updatedAll list commands support sorting with the --sort or -o flag:
- linear (default): Linear's built-in sorting order (respects manual ordering in the UI)
- created: Sort by creation date (newest first)
- updated: Sort by last update date (most recently updated first)
# Get recently updated issues
linctl issue list --sort updated
# Get oldest projects first
linctl project list --sort created
# Get recently joined users
linctl user list --sort created --active
# Get latest comments on an issue
linctl comment list LIN-123 --sort created
# Combine sorting with filters
linctl issue list --assignee me --state "In Progress" --sort updated
# Combine time filtering with sorting
linctl issue list --newer-than 1_week_ago --sort updated
# Get all projects sorted by creation date
linctl project list --newer-than all_time --sort created- The 6-month default filter significantly improves performance for large workspaces
- Use specific time ranges when possible instead of
all_time - Combine time filtering with other filters (assignee, state, team) for faster results
linctl includes comprehensive unit and integration tests to ensure reliability.
# Run all tests (currently just a smoke test)
make testIntegration tests require a Linear API key. Create a .env.test file:
cp .env.test.example .env.test
# Edit .env.test and add your LINEAR_TEST_API_KEYOr set it as an environment variable:
export LINEAR_TEST_API_KEY="your-test-api-key"
make test-integrationtests/unit/- Unit tests with mocked API responsestests/integration/- End-to-end tests with real Linear APItests/testutils/- Shared test utilities and helpers
See tests/README.md for detailed testing documentation.
Use --plaintext or --json flags for scripting:
#!/bin/bash
# Get all urgent issues in JSON format
urgent_issues=$(linctl issue list --priority 1 --json)
# Parse with jq
echo "$urgent_issues" | jq '.[] | select(.assignee == "me") | .id'
# Plaintext output for simple parsing
linctl issue list --assignee me --plaintext | cut -f1 | tail -n +2
# Get issue count for different time periods
echo "Last week: $(linctl issue list --newer-than 1_week_ago --json | jq '. | length')"
echo "Last month: $(linctl issue list --newer-than 1_month_ago --json | jq '. | length')"
echo "All time: $(linctl issue list --newer-than all_time --json | jq '. | length')"
# Create and assign issue in one command
linctl issue create --title "Fix bug" --team ENG --assign-me --json
# Get all projects for a team
linctl project list --team ENG --json | jq '.[] | {name, progress}'
# List all admin users
linctl user list --json | jq '.[] | select(.admin == true) | {name, email}'
# Get team member count
linctl team members ENG --json | jq '. | length'
# Export issue comments
linctl comment list LIN-123 --json > issue-comments.json# Find which team a user belongs to
for team in $(linctl team list --json | jq -r '.[].key'); do
echo "Checking team: $team"
linctl team members $team --json | jq '.[] | select(.email == "john@example.com")'
done
# List all private teams
linctl team list --json | jq '.[] | select(.private == true) | {key, name}'
# Get teams with more than 50 issues
linctl team list --json | jq '.[] | select(.issueCount > 50) | {key, name, issueCount}'# Find inactive users
linctl user list --json | jq '.[] | select(.active == false) | {name, email}'
# Check if you're an admin
linctl user me --json | jq '.admin'
# List users who are admins but not the current user
linctl user list --json | jq '.[] | select(.admin == true and .isMe == false) | .email'# Add a comment mentioning the issue is blocked
linctl comment create LIN-123 --body "Blocked by LIN-456. Waiting for API changes."
# Get all comments by a specific user
linctl comment list LIN-123 --json | jq '.[] | select(.user.email == "john@example.com") | .body'
# Count comments per issue
for issue in LIN-123 LIN-124 LIN-125; do
count=$(linctl comment list $issue --json | jq '. | length')
echo "$issue: $count comments"
done# List projects nearing completion (>80% progress)
linctl project list --json | jq '.[] | select(.progress > 0.8) | {name, progress}'
# Get all paused projects
linctl project list --state paused
# Show project timeline
linctl project get PROJECT-ID --json | jq '{name, startDate, targetDate, progress}'#!/bin/bash
# Show my recent activity
echo "=== My Issues ==="
linctl issue list --assignee me --limit 10
echo -e "\n=== Recent Comments ==="
for issue in $(linctl issue list --assignee me --json | jq -r '.[].identifier'); do
echo "Comments on $issue:"
linctl comment list $issue --limit 3
done# Check authentication status
linctl auth status
# Re-authenticate
linctl auth logout
linctl authLinear has the following rate limits:
- Personal API Keys: 5,000 requests/hour
Not authenticated: Runlinctl authfirstTeam not found: Use team key (e.g., "ENG") not display nameInvalid priority: Use numbers 0-4 (0=None, 1=Urgent, 2=High, 3=Normal, 4=Low)
- Missing old issues? Remember that list commands default to showing only the last 6 months
- Solution: Use
--newer-than all_timeto see all issues
- Solution: Use
- Invalid time expression? Check the format:
N_units_ago(e.g.,3_weeks_ago)- Valid units:
minutes,hours,days,weeks,months,years
- Valid units:
- Performance issues? Avoid using
all_timeon large workspaces- Solution: Use specific time ranges like
--newer-than 1_year_ago
- Solution: Use specific time ranges like
Contributions are welcome! Please see CONTRIBUTING.md for the workflow, development setup, and release process.
MIT License - see LICENSE file for details.
Built with β€οΈ using Go, Cobra, and the Linear API