linear

package
v1.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package linear provides a Go client for the Linear API with comprehensive GraphQL support, automatic rate limiting, and robust error handling.

The client supports all major Linear operations including issue management, comments, notifications, team operations, and custom metadata storage using a description-based approach.

Authentication

The client requires a Linear API token for authentication. You can provide the token directly or load it from a file:

// Direct token
client := linear.NewClient("your-api-token")

// Token from file with fallback to environment variable
client := linear.NewClientWithTokenPath("/path/to/token")

Basic Usage

Get an issue:

issue, err := client.GetIssue("issue-id")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Issue: %s - %s\n", issue.Identifier, issue.Title)

Create an issue:

issue, err := client.CreateIssue("team-id", "Bug Report", "Description here")
if err != nil {
    log.Fatal(err)
}

Update issue state:

err := client.UpdateIssueState("issue-id", "state-id")
if err != nil {
    log.Fatal(err)
}

Metadata Management

This client supports storing custom metadata in Linear issue and project descriptions using a collapsible markdown format. Metadata is automatically extracted when fetching issues/projects and preserved when updating descriptions.

Update metadata for an issue:

err := client.UpdateIssueMetadataKey("issue-id", "priority", "high")
if err != nil {
    log.Fatal(err)
}

Remove metadata:

err := client.RemoveIssueMetadataKey("issue-id", "priority")
if err != nil {
    log.Fatal(err)
}

Error Handling

The package defines custom error types for better error handling:

err := client.UpdateIssueState("issue-id", "invalid-state")
if linear.IsValidationError(err) {
    // Handle validation error
}
if linear.IsRateLimitError(err) {
    // Handle rate limit with retry
    retryAfter := linear.GetRetryAfter(err)
}

Rate Limiting

The client automatically handles rate limiting with exponential backoff and respects Linear's rate limit headers. When rate limits are exceeded, a RateLimitError is returned with retry information.

Network Resilience

The client includes automatic retry logic for transient network errors with exponential backoff. Connection failures, timeouts, and temporary DNS issues are automatically retried.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {

	// Sub-clients for different domains
	Issues        *issues.Client
	Projects      *projects.Client
	Comments      *comments.Client
	Teams         *teams.Client
	Notifications *users.NotificationClient
	Workflows     *workflows.Client
	Attachments   *attachments.Client
	Cycles        *cycles.Client
	// contains filtered or unexported fields
}

Client represents the main Linear API client that orchestrates all sub-clients. It provides a single entry point for all Linear API operations while delegating to specialized sub-clients for specific functionality.

func NewClient

func NewClient(apiToken string) *Client

NewClient creates a new Linear API client with all sub-clients initialized

func NewClientWithAuthMode added in v1.4.5

func NewClientWithAuthMode(apiToken string, authMode string) *Client

NewClientWithAuthMode creates a new Linear API client with explicit auth mode. authMode should be "user" or "agent". Empty string defaults to email suffix detection for backward compatibility with existing tokens.

func NewClientWithTokenPath

func NewClientWithTokenPath(tokenPath string) *Client

NewClientWithTokenPath creates a new Linear API client with token loading. It intelligently selects between static and refreshing token providers based on: - Whether a refresh token is available - Whether OAuth credentials are configured

func NewDefaultClient

func NewDefaultClient() *Client

NewDefaultClient creates a new Linear API client using default token path

func (*Client) AddReaction

func (c *Client) AddReaction(targetID, emoji string) error

func (*Client) ArchiveCycle

func (c *Client) ArchiveCycle(cycleID string) error

func (*Client) AssignIssue

func (c *Client) AssignIssue(identifierOrID, assigneeNameOrEmail string) error

func (*Client) CommentClient added in v1.3.0

func (c *Client) CommentClient() *comments.Client

func (*Client) CreateComment

func (c *Client) CreateComment(issueID, body string) (*core.Comment, error)

Comment operations

func (*Client) CreateCommentReply

func (c *Client) CreateCommentReply(issueID, parentID, body string) (*core.Comment, error)

func (*Client) CreateCycle

func (c *Client) CreateCycle(input *core.CreateCycleInput) (*core.Cycle, error)

func (*Client) CreateIssue

func (c *Client) CreateIssue(input *core.IssueCreateInput) (*core.Issue, error)

Issue operations

func (*Client) CreateProject

func (c *Client) CreateProject(name, description, teamKeyOrName string) (*core.Project, error)

Project operations

func (*Client) CreateRelation added in v1.5.0

func (c *Client) CreateRelation(issueID, relatedIssueID string, relationType core.IssueRelationType) error

func (*Client) CycleClient added in v1.3.0

func (c *Client) CycleClient() *cycles.Client

func (*Client) GetAPIToken

func (c *Client) GetAPIToken() string

GetAPIToken returns the current API token Why: Some operations may need direct access to the token, such as checking authentication status.

func (*Client) GetActiveCycle

func (c *Client) GetActiveCycle(teamKeyOrName string) (*core.Cycle, error)

func (*Client) GetAppUserID

func (c *Client) GetAppUserID() (string, error)

func (*Client) GetAuthMode added in v1.4.5

func (c *Client) GetAuthMode() string

GetAuthMode returns the authentication mode: "user", "agent", or "" (legacy token) Empty string indicates a legacy token without explicit auth mode

func (*Client) GetBase

func (c *Client) GetBase() *core.BaseClient

GetBase returns the base client (for testing purposes)

func (*Client) GetCommentWithReplies

func (c *Client) GetCommentWithReplies(commentID string) (*core.CommentWithReplies, error)

func (*Client) GetCycle

func (c *Client) GetCycle(cycleID string) (*core.Cycle, error)

Cycle operations

func (*Client) GetCycleIssues

func (c *Client) GetCycleIssues(cycleID string, limit int) ([]core.Issue, error)

func (*Client) GetHTTPClient

func (c *Client) GetHTTPClient() *http.Client

GetHTTPClient returns the underlying HTTP client for testing purposes

func (*Client) GetIssue

func (c *Client) GetIssue(identifierOrID string) (*core.Issue, error)

GetIssue retrieves an issue with the best context automatically determined This is the preferred method for getting issues as it intelligently chooses whether to include parent or project context based on the issue's relationships.

func (*Client) GetIssueBasic

func (c *Client) GetIssueBasic(issueID string) (*core.Issue, error)

GetIssueBasic retrieves basic issue information without additional context Use this when you only need basic issue data without parent/project details.

func (*Client) GetIssueSimplified

func (c *Client) GetIssueSimplified(issueID string) (*core.Issue, error)

GetIssueSimplified retrieves basic issue information using a simplified query Use this as a fallback when the full context queries fail due to server issues.

func (*Client) GetIssueWithParentContext

func (c *Client) GetIssueWithParentContext(issueID string) (*core.Issue, error)

DEPRECATED: Use GetIssue() instead, which automatically determines the best context

func (*Client) GetIssueWithProjectContext

func (c *Client) GetIssueWithProjectContext(issueID string) (*core.Issue, error)

DEPRECATED: Use GetIssue() instead, which automatically determines the best context

func (*Client) GetIssueWithRelations added in v1.3.0

func (c *Client) GetIssueWithRelations(identifier string) (*core.IssueWithRelations, error)

func (*Client) GetNotifications

func (c *Client) GetNotifications(includeRead bool, limit int) ([]core.Notification, error)

Notification operations

func (*Client) GetProject

func (c *Client) GetProject(projectID string) (*core.Project, error)

func (*Client) GetSubIssues

func (c *Client) GetSubIssues(parentIssueID string) ([]core.SubIssue, error)

func (*Client) GetTeam

func (c *Client) GetTeam(keyOrName string) (*core.Team, error)

func (*Client) GetTeamEstimateScale

func (c *Client) GetTeamEstimateScale(keyOrName string) (*core.EstimateScale, error)

func (*Client) GetTeams

func (c *Client) GetTeams() ([]core.Team, error)

Team operations

func (*Client) GetUser

func (c *Client) GetUser(idOrEmail string) (*core.User, error)

func (*Client) GetViewer

func (c *Client) GetViewer() (*core.User, error)

func (*Client) GetWorkflowStateByName

func (c *Client) GetWorkflowStateByName(teamID, stateName string) (*core.WorkflowState, error)

func (*Client) GetWorkflowStates

func (c *Client) GetWorkflowStates(teamID string) ([]core.WorkflowState, error)

Workflow operations

func (*Client) IsAgentMode added in v1.4.5

func (c *Client) IsAgentMode() bool

IsAgentMode returns whether the client is authenticated as an OAuth application When true, "me" resolution will use delegateId instead of assigneeId

func (*Client) IssueClient added in v1.3.0

func (c *Client) IssueClient() *issues.Client

func (*Client) ListAllIssues

func (c *Client) ListAllIssues(filter *core.IssueFilter) (*core.ListAllIssuesResult, error)

func (*Client) ListAllProjects

func (c *Client) ListAllProjects(limit int) ([]core.Project, error)

func (*Client) ListAssignedIssues

func (c *Client) ListAssignedIssues(limit int) ([]core.Issue, error)

func (*Client) ListByTeam added in v1.3.0

func (c *Client) ListByTeam(teamID string, limit int) ([]core.Project, error)

func (*Client) ListCycles

func (c *Client) ListCycles(filter *core.CycleFilter) (*core.CycleSearchResult, error)

func (*Client) ListUserProjects

func (c *Client) ListUserProjects(userID string, limit int) ([]core.Project, error)

func (*Client) ListUsers

func (c *Client) ListUsers(filter *core.UserFilter) ([]core.User, error)

User operations

func (*Client) ListUsersWithPagination

func (c *Client) ListUsersWithPagination(filter *core.UserFilter) (*core.ListUsersResult, error)

func (*Client) MarkNotificationAsRead

func (c *Client) MarkNotificationAsRead(notificationID string) error

func (*Client) ProjectClient added in v1.3.0

func (c *Client) ProjectClient() *projects.Client

func (*Client) RemoveIssueMetadataKey

func (c *Client) RemoveIssueMetadataKey(issueID, key string) error

func (*Client) RemoveProjectMetadataKey

func (c *Client) RemoveProjectMetadataKey(projectID, key string) error

func (*Client) ResolveCycleIdentifier

func (c *Client) ResolveCycleIdentifier(numberOrNameOrID string, teamID string) (string, error)

func (*Client) ResolveIssueIdentifier

func (c *Client) ResolveIssueIdentifier(identifier string) (string, error)

func (*Client) ResolveLabelIdentifier added in v1.4.0

func (c *Client) ResolveLabelIdentifier(labelName string, teamID string) (string, error)

func (*Client) ResolveProjectIdentifier added in v1.4.7

func (c *Client) ResolveProjectIdentifier(nameOrID string, teamID string) (string, error)

func (*Client) ResolveTeamIdentifier

func (c *Client) ResolveTeamIdentifier(keyOrName string) (string, error)

Resolver operations (expose resolver functionality)

func (*Client) ResolveUserIdentifier

func (c *Client) ResolveUserIdentifier(nameOrEmail string) (*ResolvedUser, error)

func (*Client) SearchIssues

func (c *Client) SearchIssues(filters *core.IssueSearchFilters) (*core.IssueSearchResult, error)

Issue search operations

func (*Client) SetBase

func (c *Client) SetBase(base *core.BaseClient)

SetBase sets the base client (for testing purposes)

func (*Client) TeamClient added in v1.3.0

func (c *Client) TeamClient() *teams.Client

func (*Client) TestConnection

func (c *Client) TestConnection() error

TestConnection tests if the client can connect to Linear API Why: Users need to verify their authentication and network connectivity before attempting other operations.

func (*Client) UpdateCycle

func (c *Client) UpdateCycle(cycleID string, input *core.UpdateCycleInput) (*core.Cycle, error)

func (*Client) UpdateIssue

func (c *Client) UpdateIssue(identifierOrID string, input core.UpdateIssueInput) (*core.Issue, error)

func (*Client) UpdateIssueDescription

func (c *Client) UpdateIssueDescription(issueID, newDescription string) error

func (*Client) UpdateIssueMetadataKey

func (c *Client) UpdateIssueMetadataKey(issueID, key string, value interface{}) error

func (*Client) UpdateIssueState

func (c *Client) UpdateIssueState(identifierOrID, stateID string) error

func (*Client) UpdateProject added in v1.3.0

func (c *Client) UpdateProject(projectID string, input interface{}) (*core.Project, error)

func (*Client) UpdateProjectDescription

func (c *Client) UpdateProjectDescription(projectID, newDescription string) error

func (*Client) UpdateProjectMetadataKey

func (c *Client) UpdateProjectMetadataKey(projectID, key string, value interface{}) error

func (*Client) UpdateProjectState

func (c *Client) UpdateProjectState(projectID, state string) error

func (*Client) WorkflowClient added in v1.3.0

func (c *Client) WorkflowClient() *workflows.Client

type ResolvedUser added in v1.4.3

type ResolvedUser struct {
	ID            string
	IsApplication bool
}

ResolvedUser contains the resolved user ID and whether it's an OAuth application

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver handles intelligent resolution of human-readable identifiers to UUIDs It manages caching and provides smart matching with ambiguity detection

Why: The MCP server should accept human-readable inputs (emails, names, CEN-123) instead of forcing clients to look up UUIDs. The resolver handles this translation.

func NewResolver

func NewResolver(client *Client) *Resolver

NewResolver creates a new resolver with the default cache TTL

func (*Resolver) ResolveCycle

func (r *Resolver) ResolveCycle(numberOrNameOrID string, teamID string) (string, error)

ResolveCycle resolves a cycle identifier (number or name) to a cycle UUID Supports: - Cycle numbers: "62" (fastest lookup) - Cycle names: "Cycle 67" or "Sprint Planning"

Returns error with suggestions if multiple cycles match

func (*Resolver) ResolveIssue

func (r *Resolver) ResolveIssue(identifier string) (string, error)

ResolveIssue resolves an issue identifier (CEN-123) to an issue UUID Only accepts Linear identifiers in format TEAM-NUMBER

Returns error if identifier invalid or issue not found

func (*Resolver) ResolveLabel added in v1.4.0

func (r *Resolver) ResolveLabel(labelName string, teamID string) (string, error)

ResolveLabel resolves a label name to a label UUID within a specific team Labels are team-scoped, so teamID is required

Returns error if label not found

func (*Resolver) ResolveProject added in v1.4.7

func (r *Resolver) ResolveProject(nameOrID string, teamID string) (string, error)

ResolveProject resolves a project identifier (name or UUID) to a project UUID Supports: - UUIDs - returned as-is - Project names: "My Project" (case-insensitive match)

When teamID is provided, only projects for that team are searched. When teamID is empty, all workspace projects are searched.

Returns error with suggestions if multiple projects match

func (*Resolver) ResolveTeam

func (r *Resolver) ResolveTeam(keyOrName string) (string, error)

ResolveTeam resolves a team identifier (name or key) to a team UUID Supports: - Team keys: "ENG", "PRODUCT" - Team names: "Engineering", "Product Team"

Returns error if team not found

func (*Resolver) ResolveUser

func (r *Resolver) ResolveUser(nameOrEmail string) (*ResolvedUser, error)

ResolveUser resolves a user identifier (email or name) to a ResolvedUser containing the UUID and whether it's an OAuth application. Supports: - "me" - resolves to the authenticated user - UUIDs - returned as-is (already resolved, IsApplication=false) - Email addresses: "[email protected]" - Display names: "John Doe" - First names: "John" (errors if ambiguous)

Returns error with suggestions if multiple users match

Directories

Path Synopsis
Package guidance provides AI agent-friendly error messages with actionable guidance.
Package guidance provides AI agent-friendly error messages with actionable guidance.
Package identifiers provides format detection and parsing for Linear identifiers.
Package identifiers provides format detection and parsing for Linear identifiers.
Package metadata provides HTML-based metadata storage for Linear issues and projects.
Package metadata provides HTML-based metadata storage for Linear issues and projects.
Package pagination provides utilities for offset-based pagination in Linear API queries.
Package pagination provides utilities for offset-based pagination in Linear API queries.
Package schema contains the Linear GraphQL schema for reference and validation.
Package schema contains the Linear GraphQL schema for reference and validation.
Package testutil provides testing utilities for Linear client tests.
Package testutil provides testing utilities for Linear client tests.
Package validation provides input validation utilities for Linear API operations.
Package validation provides input validation utilities for Linear API operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL