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
- func AuthenticationRequiredError(operation string) error
- func BatchOperationError(operation string, err error) error
- func ConfigurationError(issue string, err error) error
- func EnhanceGenericError(operation string, err error) error
- func GetImageDimensions(imageData []byte) (width, height int, err error)
- func GetRetryAfter(err error) time.Duration
- func GetSharedHTTPClient() *http.Client
- func InvalidStateIDError(stateID string, err error) error
- func IsAuthenticationError(err error) bool
- func IsGraphQLError(err error) bool
- func IsImageAttachment(attachment Attachment) bool
- func IsNotFoundError(err error) bool
- func IsRateLimitError(err error) bool
- func IsValidationError(err error) bool
- func MapSortDirection(direction string) string
- func MapSortField(sort string) string
- func NetworkRetryError(operation string, err error) error
- func NewOptimizedHTTPClient() *http.Client
- func OperationFailedError(operation, resourceType string, guidance []string) error
- func RateLimitErrorWithGuidance(operation string, retryAfter int) error
- func ResourceNotFoundError(resourceType, resourceID string, err error) error
- func ValidationErrorWithExample(field, requirement, example string) error
- type Attachment
- type AttachmentCache
- type AttachmentClient
- func (ac *AttachmentClient) GetAttachment(attachmentURL string, format AttachmentFormat) (*AttachmentResponse, error)
- func (ac *AttachmentClient) UploadFile(filename string, content []byte, contentType string) (string, error)
- func (ac *AttachmentClient) UploadFileFromPath(filepath string) (string, error)
- type AttachmentConnection
- type AttachmentFormat
- type AttachmentResponse
- type AuthenticationError
- type BaseClient
- type BatchIssueUpdate
- type BatchIssueUpdateResult
- type CacheEntry
- type CapacityRecommendation
- type ChildrenNodes
- type Client
- func (c *Client) AddReaction(targetID, emoji string) error
- func (c *Client) ArchiveCycle(cycleID string) error
- func (c *Client) AssignIssue(identifierOrID, assigneeNameOrEmail string) error
- func (c *Client) CreateComment(issueID, body string) (string, error)
- func (c *Client) CreateCommentReply(issueID, parentID, body string) (string, error)
- func (c *Client) CreateCycle(input *CreateCycleInput) (*Cycle, error)
- func (c *Client) CreateIssue(title, description, teamKeyOrName string) (*Issue, error)
- func (c *Client) CreateProject(name, description, teamKeyOrName string) (*Project, error)
- func (c *Client) GetAPIToken() string
- func (c *Client) GetActiveCycle(teamKeyOrName string) (*Cycle, error)
- func (c *Client) GetAppUserID() (string, error)
- func (c *Client) GetBase() *BaseClient
- func (c *Client) GetCommentWithReplies(commentID string) (*CommentWithReplies, error)
- func (c *Client) GetCycle(cycleID string) (*Cycle, error)
- func (c *Client) GetCycleIssues(cycleID string, limit int) ([]Issue, error)
- func (c *Client) GetHTTPClient() *http.Client
- func (c *Client) GetIssue(identifierOrID string) (*Issue, error)
- func (c *Client) GetIssueBasic(issueID string) (*Issue, error)
- func (c *Client) GetIssueSimplified(issueID string) (*Issue, error)
- func (c *Client) GetIssueWithParentContext(issueID string) (*Issue, error)
- func (c *Client) GetIssueWithProjectContext(issueID string) (*Issue, error)
- func (c *Client) GetNotifications(includeRead bool, limit int) ([]Notification, error)
- func (c *Client) GetProject(projectID string) (*Project, error)
- func (c *Client) GetSubIssues(parentIssueID string) ([]SubIssue, error)
- func (c *Client) GetTeam(keyOrName string) (*Team, error)
- func (c *Client) GetTeamEstimateScale(keyOrName string) (*EstimateScale, error)
- func (c *Client) GetTeams() ([]Team, error)
- func (c *Client) GetUser(idOrEmail string) (*User, error)
- func (c *Client) GetViewer() (*User, error)
- func (c *Client) GetWorkflowStateByName(teamID, stateName string) (*WorkflowState, error)
- func (c *Client) GetWorkflowStates(teamID string) ([]WorkflowState, error)
- func (c *Client) ListAllIssues(filter *IssueFilter) (*ListAllIssuesResult, error)
- func (c *Client) ListAllProjects() ([]Project, error)
- func (c *Client) ListAssignedIssues(userID string) ([]Issue, error)
- func (c *Client) ListCycles(filter *CycleFilter) (*CycleSearchResult, error)
- func (c *Client) ListUserProjects(userID string) ([]Project, error)
- func (c *Client) ListUsers(filter *UserFilter) ([]User, error)
- func (c *Client) ListUsersWithPagination(filter *UserFilter) (*ListUsersResult, error)
- func (c *Client) MarkNotificationAsRead(notificationID string) error
- func (c *Client) RemoveIssueMetadataKey(issueID, key string) error
- func (c *Client) RemoveProjectMetadataKey(projectID, key string) error
- func (c *Client) ResolveCycleIdentifier(numberOrNameOrID string, teamID string) (string, error)
- func (c *Client) ResolveIssueIdentifier(identifier string) (string, error)
- func (c *Client) ResolveTeamIdentifier(keyOrName string) (string, error)
- func (c *Client) ResolveUserIdentifier(nameOrEmail string) (string, error)
- func (c *Client) SearchIssues(filters *IssueSearchFilters) (*IssueSearchResult, error)
- func (c *Client) SetBase(base *BaseClient)
- func (c *Client) TestConnection() error
- func (c *Client) UpdateCycle(cycleID string, input *UpdateCycleInput) (*Cycle, error)
- func (c *Client) UpdateIssue(identifierOrID string, input UpdateIssueInput) (*Issue, error)
- func (c *Client) UpdateIssueDescription(issueID, newDescription string) error
- func (c *Client) UpdateIssueMetadataKey(issueID, key string, value interface{}) error
- func (c *Client) UpdateIssueState(identifierOrID, stateID string) error
- func (c *Client) UpdateProjectDescription(projectID, newDescription string) error
- func (c *Client) UpdateProjectMetadataKey(projectID, key string, value interface{}) error
- func (c *Client) UpdateProjectState(projectID, state string) error
- type Comment
- type CommentClient
- func (cc *CommentClient) AddReaction(targetID, emoji string) error
- func (cc *CommentClient) CreateComment(issueID, body string) (*Comment, error)
- func (cc *CommentClient) CreateCommentReply(issueID, parentID, body string) (*Comment, error)
- func (cc *CommentClient) GetCommentWithReplies(commentID string) (*CommentWithReplies, error)
- func (cc *CommentClient) GetIssueComments(issueID string) ([]Comment, error)
- type CommentConnection
- type CommentIssue
- type CommentParent
- type CommentWithReplies
- type CreateCycleInput
- type Cycle
- type CycleAnalysis
- type CycleClient
- func (cc *CycleClient) ArchiveCycle(cycleID string) error
- func (cc *CycleClient) CreateCycle(input *CreateCycleInput) (*Cycle, error)
- func (cc *CycleClient) GetActiveCycle(teamID string) (*Cycle, error)
- func (cc *CycleClient) GetCycle(cycleID string) (*Cycle, error)
- func (cc *CycleClient) GetCycleIssues(cycleID string, limit int) ([]Issue, error)
- func (cc *CycleClient) ListCycles(filter *CycleFilter) (*CycleSearchResult, error)
- func (cc *CycleClient) UpdateCycle(cycleID string, input *UpdateCycleInput) (*Cycle, error)
- type CycleCompact
- type CycleFilter
- type CycleMetrics
- type CycleMinimal
- type CycleReference
- type CycleSearchResult
- type ErrorWithGuidance
- type EstimateScale
- type ExternalUser
- type FileUploadResponse
- type GraphQLError
- type HTTPError
- type Issue
- type IssueClient
- func (ic *IssueClient) AssignIssue(issueID, assigneeID string) error
- func (ic *IssueClient) BatchUpdateIssues(issueIDs []string, update BatchIssueUpdate) (*BatchIssueUpdateResult, error)
- func (ic *IssueClient) CreateIssue(title, description, teamID string) (*Issue, error)
- func (ic *IssueClient) GetIssue(issueID string) (*Issue, error)
- func (ic *IssueClient) GetIssueSimplified(issueID string) (*Issue, error)
- func (ic *IssueClient) GetIssueWithBestContext(issueID string) (*Issue, error)
- func (ic *IssueClient) GetIssueWithFallback(issueID string) (*Issue, error)
- func (ic *IssueClient) GetIssueWithParentContext(issueID string) (*Issue, error)
- func (ic *IssueClient) GetIssueWithProjectContext(issueID string) (*Issue, error)
- func (ic *IssueClient) GetIssueWithRelations(issueID string) (*IssueWithRelations, error)
- func (ic *IssueClient) GetSubIssues(parentIssueID string) ([]SubIssue, error)
- func (ic *IssueClient) GetTeamIssuesWithRelations(teamID string, limit int) ([]IssueWithRelations, error)
- func (ic *IssueClient) ListAllIssues(filter *IssueFilter) (*ListAllIssuesResult, error)
- func (ic *IssueClient) ListAssignedIssues(limit int) ([]Issue, error)
- func (ic *IssueClient) ListIssueAttachments(issueID string) ([]Attachment, error)
- func (ic *IssueClient) RemoveIssueMetadataKey(issueID, key string) error
- func (ic *IssueClient) SearchIssuesEnhanced(filters *IssueSearchFilters) (*IssueSearchResult, error)
- func (ic *IssueClient) UpdateIssue(issueID string, input UpdateIssueInput) (*Issue, error)
- func (ic *IssueClient) UpdateIssueDescription(issueID, newDescription string) error
- func (ic *IssueClient) UpdateIssueMetadataKey(issueID, key string, value interface{}) error
- func (ic *IssueClient) UpdateIssueState(issueID, stateID string) error
- type IssueCompact
- type IssueConnection
- type IssueFilter
- type IssueMinimal
- type IssueRelation
- type IssueRelationConnection
- type IssueRelationType
- type IssueSearchFilters
- type IssueSearchResult
- type IssueWithDetails
- type IssueWithRelations
- type Label
- type LabelConnection
- type ListAllIssuesResult
- type ListUsersResult
- type NotFoundError
- type Notification
- type NotificationClient
- type NotificationComment
- type NotificationIssue
- type PaginationInput
- type ParentIssue
- type Project
- type ProjectClient
- func (pc *ProjectClient) CreateProject(name, description, teamID string) (*Project, error)
- func (pc *ProjectClient) GetProject(projectID string) (*Project, error)
- func (pc *ProjectClient) ListAllProjects(limit int) ([]Project, error)
- func (pc *ProjectClient) ListUserProjects(userID string, limit int) ([]Project, error)
- func (pc *ProjectClient) RemoveProjectMetadataKey(projectID, key string) error
- func (pc *ProjectClient) UpdateProject(projectID string, input UpdateProjectInput) (*Project, error)
- func (pc *ProjectClient) UpdateProjectDescription(projectID, newContent string) error
- func (pc *ProjectClient) UpdateProjectMetadataKey(projectID, key string, value interface{}) error
- func (pc *ProjectClient) UpdateProjectState(projectID, state string) error
- type ProjectIssue
- type RateLimitError
- type Resolver
- type ResponseFormat
- type SubIssue
- type Team
- type TeamClient
- func (tc *TeamClient) GetTeam(teamID string) (*Team, error)
- func (tc *TeamClient) GetTeams() ([]Team, error)
- func (tc *TeamClient) GetUser(userID string) (*User, error)
- func (tc *TeamClient) GetUserByEmail(email string) (*User, error)
- func (tc *TeamClient) GetViewer() (*User, error)
- func (tc *TeamClient) ListLabels(teamID string) ([]Label, error)
- func (tc *TeamClient) ListUsers(filter *UserFilter) ([]User, error)
- func (tc *TeamClient) ListUsersWithDisplayNameFilter(displayName string, activeOnly *bool, limit int) ([]User, error)
- func (tc *TeamClient) ListUsersWithPagination(filter *UserFilter) (*ListUsersResult, error)
- type UpdateCycleInput
- type UpdateIssueInput
- type UpdateProjectInput
- type User
- type UserFilter
- type ValidationError
- type WorkflowClient
- type WorkflowState
Constants ¶
const ( // MaxTitleLength is the maximum length for issue titles in Linear MaxTitleLength = 255 // MaxDescriptionLength is the maximum length for descriptions in Linear MaxDescriptionLength = 100000 // MaxNotificationLimit is the maximum number of notifications that can be fetched MaxNotificationLimit = 100 )
Constants for validation limits
const MCPSizeLimit = 1024 * 1024 // 1MB
MCPSizeLimit is the 1MB limit for MCP content (Claude Desktop constraint)
Variables ¶
This section is empty.
Functions ¶
func AuthenticationRequiredError ¶
AuthenticationRequiredError creates an error when authentication is needed
func BatchOperationError ¶
BatchOperationError creates an error for batch operations
func ConfigurationError ¶
ConfigurationError creates an error for configuration issues
func EnhanceGenericError ¶
EnhanceGenericError takes a generic error and adds context
func GetImageDimensions ¶
GetImageDimensions returns dimensions of image data
func GetRetryAfter ¶
GetRetryAfter extracts the retry duration from a RateLimitError Returns 0 if the error is not a RateLimitError or has no retry duration
func GetSharedHTTPClient ¶
GetSharedHTTPClient returns the shared HTTP client instance This should be used for OAuth and other non-API operations that don't need per-client authentication headers
func InvalidStateIDError ¶
InvalidStateIDError creates an error for invalid state IDs with guidance
func IsAuthenticationError ¶
IsAuthenticationError checks if an error is an AuthenticationError It uses errors.As to handle wrapped errors
func IsGraphQLError ¶
IsGraphQLError checks if an error is a GraphQLError It uses errors.As to handle wrapped errors
func IsImageAttachment ¶
func IsImageAttachment(attachment Attachment) bool
IsImageAttachment checks if an attachment is an image based on content type
func IsNotFoundError ¶
IsNotFoundError checks if an error is a NotFoundError It uses errors.As to handle wrapped errors
func IsRateLimitError ¶
IsRateLimitError checks if an error is a RateLimitError It uses errors.As to handle wrapped errors
func IsValidationError ¶
IsValidationError checks if an error is a ValidationError It uses errors.As to handle wrapped errors
func MapSortDirection ¶
MapSortDirection converts user-facing direction to GraphQL direction
func MapSortField ¶
MapSortField converts user-facing sort names to Linear's PaginationOrderBy enum Returns empty string for priority (client-side sorting required)
func NetworkRetryError ¶
NetworkRetryError creates an error with retry guidance
func NewOptimizedHTTPClient ¶
NewOptimizedHTTPClient creates an HTTP client optimized for Linear API usage
func OperationFailedError ¶
OperationFailedError creates an error when an operation fails without clear reason
func RateLimitErrorWithGuidance ¶
RateLimitErrorWithGuidance creates an error with rate limit guidance
func ResourceNotFoundError ¶
ResourceNotFoundError creates an error when a resource is not found
func ValidationErrorWithExample ¶
ValidationError creates an error for invalid input with examples
Types ¶
type Attachment ¶
type Attachment struct {
ID string `json:"id"`
URL string `json:"url"`
Title string `json:"title"`
Subtitle string `json:"subtitle,omitempty"`
Filename string `json:"filename,omitempty"` // From UploadFile if available
ContentType string `json:"contentType,omitempty"` // From UploadFile if available
Size int64 `json:"size,omitempty"` // From UploadFile if available
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
ArchivedAt *string `json:"archivedAt,omitempty"`
Creator *User `json:"creator,omitempty"`
ExternalCreator *ExternalUser `json:"externalUserCreator,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"` // Custom metadata
Source map[string]interface{} `json:"source,omitempty"` // Source information
SourceType string `json:"sourceType,omitempty"`
GroupBySource bool `json:"groupBySource"`
Issue *Issue `json:"issue,omitempty"` // Parent issue
OriginalIssue *Issue `json:"originalIssue,omitempty"` // If moved/copied
}
Attachment represents a file attachment on an issue Based on Linear's GraphQL schema research
func FilterImageAttachments ¶
func FilterImageAttachments(attachments []Attachment) []Attachment
FilterImageAttachments returns only image attachments from a slice
type AttachmentCache ¶
type AttachmentCache struct {
// contains filtered or unexported fields
}
AttachmentCache provides in-memory caching for processed attachments
func NewAttachmentCache ¶
func NewAttachmentCache(ttl time.Duration) *AttachmentCache
NewAttachmentCache creates a new attachment cache with specified TTL
func (*AttachmentCache) Clear ¶
func (cache *AttachmentCache) Clear()
Clear removes all entries from the cache
func (*AttachmentCache) Get ¶
func (cache *AttachmentCache) Get(key string) *CacheEntry
Get retrieves a cache entry if it exists and hasn't expired
func (*AttachmentCache) Set ¶
func (cache *AttachmentCache) Set(key string, entry *CacheEntry)
Set stores a cache entry
func (*AttachmentCache) Size ¶
func (cache *AttachmentCache) Size() int
Size returns the current number of cached entries
type AttachmentClient ¶
type AttachmentClient struct {
// contains filtered or unexported fields
}
AttachmentClient handles attachment download and processing operations
func NewAttachmentClient ¶
func NewAttachmentClient(base *BaseClient) *AttachmentClient
NewAttachmentClient creates a new attachment client
func (*AttachmentClient) GetAttachment ¶
func (ac *AttachmentClient) GetAttachment(attachmentURL string, format AttachmentFormat) (*AttachmentResponse, error)
GetAttachment downloads and processes an attachment with the specified format Note: This is a simplified implementation that expects the full attachment URL to be passed as attachmentID In practice, this would be enhanced to properly resolve attachment IDs to URLs
func (*AttachmentClient) UploadFile ¶
func (ac *AttachmentClient) UploadFile(filename string, content []byte, contentType string) (string, error)
UploadFile uploads a file to Linear and returns the asset URL This implements the full upload flow: 1. Call fileUpload mutation to get upload URL and headers 2. PUT the file content to the upload URL 3. Return the asset URL for use in markdown
func (*AttachmentClient) UploadFileFromPath ¶
func (ac *AttachmentClient) UploadFileFromPath(filepath string) (string, error)
UploadFileFromPath uploads a file from a filesystem path
type AttachmentConnection ¶
type AttachmentConnection struct {
Nodes []Attachment `json:"nodes,omitempty"`
}
AttachmentConnection represents a paginated collection of attachments
type AttachmentFormat ¶
type AttachmentFormat string
AttachmentFormat defines the supported return formats for attachments
const ( FormatBase64 AttachmentFormat = "base64" // Base64 encoded content (default for MCP) FormatURL AttachmentFormat = "url" // Direct URL (for large files) FormatMetadata AttachmentFormat = "metadata" // Metadata only, no download )
type AttachmentResponse ¶
type AttachmentResponse struct {
Format AttachmentFormat `json:"format"`
Content string `json:"content,omitempty"` // Base64 content or URL
URL string `json:"url,omitempty"` // Original URL
ContentType string `json:"contentType,omitempty"` // MIME type
Size int64 `json:"size,omitempty"` // Content size in bytes
Width int `json:"width,omitempty"` // Image width (if image)
Height int `json:"height,omitempty"` // Image height (if image)
Resized bool `json:"resized,omitempty"` // True if image was resized for MCP limits
Error string `json:"error,omitempty"` // Error message if download failed
}
AttachmentResponse represents the response from GetAttachment
type AuthenticationError ¶
type AuthenticationError struct {
Message string // Human-readable error message
Code string // Error code from the API (e.g., "INVALID_TOKEN", "TOKEN_EXPIRED")
}
AuthenticationError represents an authentication failure It provides details about why authentication failed
func (*AuthenticationError) Error ¶
func (e *AuthenticationError) Error() string
Error implements the error interface for AuthenticationError
type BaseClient ¶
type BaseClient struct {
// contains filtered or unexported fields
}
BaseClient contains the shared HTTP client and common request functionality that all sub-clients will use. This ensures we have a single HTTP client instance and consistent request handling across all Linear API operations.
func NewBaseClient ¶
func NewBaseClient(apiToken string) *BaseClient
NewBaseClient creates a new base client with a shared HTTP client. For backward compatibility, this wraps the API token in a StaticProvider.
func NewBaseClientWithProvider ¶ added in v1.1.0
func NewBaseClientWithProvider(provider token.TokenProvider) *BaseClient
NewBaseClientWithProvider creates a new base client with a custom token provider. This enables automatic token refresh for OAuth apps with expiring tokens.
func NewTestBaseClient ¶
func NewTestBaseClient(apiToken string, baseURL string, httpClient *http.Client) *BaseClient
NewTestBaseClient creates a new base client for testing with custom URL
func (*BaseClient) SetHTTPClient ¶
func (bc *BaseClient) SetHTTPClient(client *http.Client)
SetHTTPClient sets a custom HTTP client for testing purposes
type BatchIssueUpdate ¶
type BatchIssueUpdate struct {
StateID string `json:"stateId,omitempty"`
AssigneeID string `json:"assigneeId,omitempty"`
LabelIDs []string `json:"labelIds,omitempty"`
Priority *int `json:"priority,omitempty"`
ProjectID string `json:"projectId,omitempty"`
}
BatchIssueUpdate represents update fields for batch operations
type BatchIssueUpdateResult ¶
type BatchIssueUpdateResult struct {
Success bool `json:"success"`
UpdatedIssues []Issue `json:"updatedIssues"`
}
BatchIssueUpdateResult represents the result of a batch update operation
type CacheEntry ¶
type CacheEntry struct {
Content []byte
ContentType string
Size int64
Width int
Height int
Resized bool
ExpiresAt time.Time
}
CacheEntry represents a cached attachment with expiration
type CapacityRecommendation ¶
type CapacityRecommendation struct {
ConservativeScope int // P80 velocity
TargetScope int // Median velocity
OptimisticScope int // P20 velocity
ConservativeIssues int // Based on avg points/issue
TargetIssues int
OptimisticIssues int
Rationale string // Explanation of calculation
}
CapacityRecommendation represents suggested cycle scope based on historical data
func GenerateCapacityRecommendation ¶
func GenerateCapacityRecommendation(analysis *CycleAnalysis, isPerUser bool) *CapacityRecommendation
GenerateCapacityRecommendation creates scope recommendations based on analysis
type ChildrenNodes ¶
type ChildrenNodes struct {
Nodes []SubIssue `json:"nodes"`
}
ChildrenNodes represents the children structure from GraphQL
type Client ¶
type Client struct {
// Sub-clients for different domains
Issues *IssueClient
Projects *ProjectClient
Comments *CommentClient
Teams *TeamClient
Notifications *NotificationClient
Workflows *WorkflowClient
Attachments *AttachmentClient
Cycles *CycleClient
// 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 NewClientWithTokenPath ¶
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 (*Client) ArchiveCycle ¶
func (*Client) AssignIssue ¶
func (*Client) CreateComment ¶
Comment operations
func (*Client) CreateCommentReply ¶
func (*Client) CreateCycle ¶
func (c *Client) CreateCycle(input *CreateCycleInput) (*Cycle, error)
func (*Client) CreateIssue ¶
Issue operations
func (*Client) CreateProject ¶
Project operations
func (*Client) GetAPIToken ¶
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 (*Client) GetAppUserID ¶
func (*Client) GetBase ¶
func (c *Client) GetBase() *BaseClient
GetBase returns the base client (for testing purposes)
func (*Client) GetCommentWithReplies ¶
func (c *Client) GetCommentWithReplies(commentID string) (*CommentWithReplies, error)
func (*Client) GetCycleIssues ¶
func (*Client) GetHTTPClient ¶
GetHTTPClient returns the underlying HTTP client for testing purposes
func (*Client) GetIssue ¶
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 ¶
GetIssueBasic retrieves basic issue information without additional context Use this when you only need basic issue data without parent/project details.
func (*Client) GetIssueSimplified ¶
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 ¶
DEPRECATED: Use GetIssue() instead, which automatically determines the best context
func (*Client) GetIssueWithProjectContext ¶
DEPRECATED: Use GetIssue() instead, which automatically determines the best context
func (*Client) GetNotifications ¶
func (c *Client) GetNotifications(includeRead bool, limit int) ([]Notification, error)
Notification operations
func (*Client) GetSubIssues ¶
func (*Client) GetTeamEstimateScale ¶
func (c *Client) GetTeamEstimateScale(keyOrName string) (*EstimateScale, error)
func (*Client) GetWorkflowStateByName ¶
func (c *Client) GetWorkflowStateByName(teamID, stateName string) (*WorkflowState, error)
func (*Client) GetWorkflowStates ¶
func (c *Client) GetWorkflowStates(teamID string) ([]WorkflowState, error)
Workflow operations
func (*Client) ListAllIssues ¶
func (c *Client) ListAllIssues(filter *IssueFilter) (*ListAllIssuesResult, error)
func (*Client) ListAllProjects ¶
func (*Client) ListAssignedIssues ¶
func (*Client) ListCycles ¶
func (c *Client) ListCycles(filter *CycleFilter) (*CycleSearchResult, error)
func (*Client) ListUserProjects ¶
func (*Client) ListUsers ¶
func (c *Client) ListUsers(filter *UserFilter) ([]User, error)
User operations
func (*Client) ListUsersWithPagination ¶
func (c *Client) ListUsersWithPagination(filter *UserFilter) (*ListUsersResult, error)
func (*Client) MarkNotificationAsRead ¶
func (*Client) RemoveIssueMetadataKey ¶
func (*Client) RemoveProjectMetadataKey ¶
func (*Client) ResolveCycleIdentifier ¶
func (*Client) ResolveIssueIdentifier ¶
func (*Client) ResolveTeamIdentifier ¶
Resolver operations (expose resolver functionality)
func (*Client) ResolveUserIdentifier ¶
func (*Client) SearchIssues ¶
func (c *Client) SearchIssues(filters *IssueSearchFilters) (*IssueSearchResult, error)
Issue search operations
func (*Client) SetBase ¶
func (c *Client) SetBase(base *BaseClient)
SetBase sets the base client (for testing purposes)
func (*Client) TestConnection ¶
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 *UpdateCycleInput) (*Cycle, error)
func (*Client) UpdateIssue ¶
func (c *Client) UpdateIssue(identifierOrID string, input UpdateIssueInput) (*Issue, error)
func (*Client) UpdateIssueDescription ¶
func (*Client) UpdateIssueMetadataKey ¶
func (*Client) UpdateIssueState ¶
func (*Client) UpdateProjectDescription ¶
func (*Client) UpdateProjectMetadataKey ¶
func (*Client) UpdateProjectState ¶
type Comment ¶
type Comment struct {
ID string `json:"id"`
Body string `json:"body"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
User User `json:"user"`
Issue CommentIssue `json:"issue"`
Parent *CommentParent `json:"parent,omitempty"`
}
Comment represents a Linear comment
type CommentClient ¶
type CommentClient struct {
// contains filtered or unexported fields
}
CommentClient handles all comment and reaction operations for the Linear API. It uses the shared BaseClient for HTTP communication and focuses on collaboration features like comments, replies, and reactions.
func NewCommentClient ¶
func NewCommentClient(base *BaseClient) *CommentClient
NewCommentClient creates a new comment client with the provided base client
func (*CommentClient) AddReaction ¶
func (cc *CommentClient) AddReaction(targetID, emoji string) error
AddReaction adds an emoji reaction to an issue or comment Why: Reactions provide quick, non-verbal feedback on issues and comments. They're useful for acknowledging, agreeing, or expressing sentiment.
func (*CommentClient) CreateComment ¶
func (cc *CommentClient) CreateComment(issueID, body string) (*Comment, error)
CreateComment creates a new comment on an issue Why: Comments are essential for collaboration on issues. This method enables users to add context, updates, and discussions to issues.
func (*CommentClient) CreateCommentReply ¶
func (cc *CommentClient) CreateCommentReply(issueID, parentID, body string) (*Comment, error)
CreateCommentReply creates a reply to an existing comment Why: Threaded discussions allow for more organized conversations. This method enables users to reply directly to specific comments.
func (*CommentClient) GetCommentWithReplies ¶
func (cc *CommentClient) GetCommentWithReplies(commentID string) (*CommentWithReplies, error)
GetCommentWithReplies retrieves a comment and all its replies Why: Understanding the full context of a discussion requires seeing all replies. This method provides the complete comment thread.
func (*CommentClient) GetIssueComments ¶
func (cc *CommentClient) GetIssueComments(issueID string) ([]Comment, error)
GetIssueComments retrieves all comments for an issue
type CommentConnection ¶
type CommentConnection struct {
Nodes []Comment `json:"nodes,omitempty"`
}
CommentConnection represents a paginated collection of comments
type CommentIssue ¶
type CommentIssue struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
}
CommentIssue represents the issue a comment belongs to
type CommentParent ¶
type CommentParent struct {
ID string `json:"id"`
}
CommentParent represents the parent of a comment reply
type CommentWithReplies ¶
type CommentWithReplies struct {
Comment Comment `json:"comment"`
Replies []Comment `json:"replies"`
}
CommentWithReplies represents a comment with all its replies
type CreateCycleInput ¶
type CreateCycleInput struct {
TeamID string `json:"teamId"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
StartsAt string `json:"startsAt"`
EndsAt string `json:"endsAt"`
}
CreateCycleInput represents the input for creating a cycle
type Cycle ¶
type Cycle struct {
ID string `json:"id"`
Name string `json:"name"`
Number int `json:"number"`
Description string `json:"description,omitempty"`
StartsAt string `json:"startsAt"`
EndsAt string `json:"endsAt"`
CompletedAt *string `json:"completedAt,omitempty"`
Progress float64 `json:"progress"`
Team *Team `json:"team,omitempty"`
IsActive bool `json:"isActive"`
IsFuture bool `json:"isFuture"`
IsPast bool `json:"isPast"`
IsNext bool `json:"isNext"`
IsPrevious bool `json:"isPrevious"`
ScopeHistory []int `json:"scopeHistory,omitempty"`
CompletedScopeHistory []int `json:"completedScopeHistory,omitempty"`
CompletedIssueCountHistory []int `json:"completedIssueCountHistory,omitempty"`
InProgressScopeHistory []int `json:"inProgressScopeHistory,omitempty"`
IssueCountHistory []int `json:"issueCountHistory,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
ArchivedAt *string `json:"archivedAt,omitempty"`
AutoArchivedAt *string `json:"autoArchivedAt,omitempty"`
}
Cycle represents a Linear cycle (sprint/iteration)
func (*Cycle) ToCompact ¶
func (c *Cycle) ToCompact() CycleCompact
ToCompact converts a full Cycle to CycleCompact
func (*Cycle) ToMinimal ¶
func (c *Cycle) ToMinimal() CycleMinimal
ToMinimal converts a full Cycle to CycleMinimal
type CycleAnalysis ¶
type CycleAnalysis struct {
CycleCount int
Metrics []CycleMetrics
// Summary statistics
AvgVelocity float64 // average completedScope
AvgCompletionRate float64
AvgScopeCreep float64
AvgScopeCreepPercent float64
AvgThroughput float64
// Statistical measures
StdDevVelocity float64
MedianVelocity float64
P80Velocity float64 // 80th percentile (conservative)
P20Velocity float64 // 20th percentile (optimistic)
}
CycleAnalysis represents aggregated metrics across multiple cycles
func AnalyzeMultipleCycles ¶
func AnalyzeMultipleCycles(cycles []*Cycle, userIssues map[string][]Issue) *CycleAnalysis
AnalyzeMultipleCycles aggregates metrics across multiple cycles
type CycleClient ¶
type CycleClient struct {
// contains filtered or unexported fields
}
CycleClient handles all cycle-related operations for the Linear API. It uses the shared BaseClient for HTTP communication and focuses on cycle (sprint/iteration) management functionality.
func NewCycleClient ¶
func NewCycleClient(base *BaseClient) *CycleClient
NewCycleClient creates a new cycle client with the provided base client
func (*CycleClient) ArchiveCycle ¶
func (cc *CycleClient) ArchiveCycle(cycleID string) error
ArchiveCycle archives a cycle Why: Completed or obsolete cycles should be archived to keep the workspace clean.
func (*CycleClient) CreateCycle ¶
func (cc *CycleClient) CreateCycle(input *CreateCycleInput) (*Cycle, error)
CreateCycle creates a new cycle in Linear Why: Teams need to create new sprints/iterations for planning work.
func (*CycleClient) GetActiveCycle ¶
func (cc *CycleClient) GetActiveCycle(teamID string) (*Cycle, error)
GetActiveCycle retrieves the current active cycle for a team Why: Most common use case is finding what cycle is currently active for sprint planning and issue assignment.
func (*CycleClient) GetCycle ¶
func (cc *CycleClient) GetCycle(cycleID string) (*Cycle, error)
GetCycle retrieves a single cycle by ID Why: This is the primary method for fetching detailed cycle information including progress metrics and state indicators.
func (*CycleClient) GetCycleIssues ¶
func (cc *CycleClient) GetCycleIssues(cycleID string, limit int) ([]Issue, error)
GetCycleIssues retrieves issues for a specific cycle Why: Users need to see all issues in a cycle for sprint planning, progress tracking, and workload analysis.
func (*CycleClient) ListCycles ¶
func (cc *CycleClient) ListCycles(filter *CycleFilter) (*CycleSearchResult, error)
ListCycles retrieves cycles with optional filtering Why: Users need to discover and browse cycles by team, status (active/future/past), with pagination support for large cycle histories.
func (*CycleClient) UpdateCycle ¶
func (cc *CycleClient) UpdateCycle(cycleID string, input *UpdateCycleInput) (*Cycle, error)
UpdateCycle updates an existing cycle Why: Teams need to modify cycle dates, names, or mark cycles as completed.
type CycleCompact ¶
type CycleCompact struct {
ID string `json:"id"`
Name string `json:"name"`
Number int `json:"number"`
StartsAt string `json:"startsAt"`
EndsAt string `json:"endsAt"`
Progress float64 `json:"progress"`
IsActive bool `json:"isActive"`
IsFuture bool `json:"isFuture"`
IsPast bool `json:"isPast"`
}
CycleCompact represents a compact cycle (~80 tokens) Use this when you need more context than minimal but not full details
type CycleFilter ¶
type CycleFilter struct {
TeamID string `json:"teamId,omitempty"`
IsActive *bool `json:"isActive,omitempty"`
IsFuture *bool `json:"isFuture,omitempty"`
IsPast *bool `json:"isPast,omitempty"`
IncludeArchived bool `json:"includeArchived,omitempty"`
Limit int `json:"limit"`
After string `json:"after,omitempty"`
Format ResponseFormat `json:"format,omitempty"`
}
CycleFilter represents filter options for listing cycles
type CycleMetrics ¶
type CycleMetrics struct {
CycleID string
CycleName string
StartDate string
EndDate string
CompletedAt *string
// Scope metrics
InitialScope int // scopeHistory[0] or sum of initial issue estimates
FinalScope int // scopeHistory[last] or sum of final issue estimates
CompletedScope int // completedScopeHistory[last] or sum of completed issue estimates
ScopeCreep int // finalScope - initialScope
ScopeCreepPercent float64 // (scopeCreep / initialScope) * 100
// Completion metrics
CompletionRate float64 // (completedScope / finalScope) * 100
// Issue metrics
InitialIssueCount int // issueCountHistory[0] or count of initial issues
CompletedIssues int // completedIssueCountHistory[last] or count of completed issues
Throughput int // completedIssues
}
CycleMetrics represents calculated metrics for a single cycle
func CalculateCycleMetrics ¶
func CalculateCycleMetrics(cycle *Cycle, userIssues []Issue) *CycleMetrics
CalculateCycleMetrics calculates metrics for a single cycle If userIssues is nil/empty, uses cycle history arrays (team-wide analysis) If userIssues is provided, calculates from filtered issues (per-user analysis)
type CycleMinimal ¶
type CycleMinimal struct {
ID string `json:"id"`
Name string `json:"name"`
Number int `json:"number"`
IsActive bool `json:"isActive"`
}
CycleMinimal represents a minimal cycle (~30 tokens) Use this for efficient browsing and list operations
type CycleReference ¶
type CycleReference struct {
ID string `json:"id"`
Name string `json:"name"`
Number int `json:"number"`
}
CycleReference represents a minimal cycle reference for Issue.Cycle field
type CycleSearchResult ¶
type CycleSearchResult struct {
Cycles []Cycle `json:"cycles"`
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
}
CycleSearchResult represents the result of searching cycles with pagination
type ErrorWithGuidance ¶
type ErrorWithGuidance struct {
Operation string // What operation failed
Reason string // Why it failed
Guidance []string // Steps to resolve
Tools []string // MCP tools that might help
Example string // Example of correct usage
OriginalErr error // Original error for debugging
}
ErrorWithGuidance creates an error with actionable guidance for agents
func (*ErrorWithGuidance) Error ¶
func (e *ErrorWithGuidance) Error() string
func (*ErrorWithGuidance) Unwrap ¶
func (e *ErrorWithGuidance) Unwrap() error
Unwrap returns the original error for errors.As/Is/Unwrap support
type EstimateScale ¶
type EstimateScale struct {
Type string `json:"type"` // notUsed, exponential, fibonacci, linear, tShirt
AllowZero bool `json:"allowZero"` // Whether 0 is allowed
Extended bool `json:"extended"` // Whether extended values are enabled
DefaultEstimate *float64 `json:"defaultEstimate"` // Default value
Values []float64 `json:"values"` // Available estimate values
Labels []string `json:"labels"` // Human-readable labels (for tShirt)
}
EstimateScale represents the available estimate values for a team
type ExternalUser ¶
type ExternalUser struct {
ID string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Email string `json:"email,omitempty"`
}
ExternalUser represents a user from external systems (like Slack)
type FileUploadResponse ¶
type FileUploadResponse struct {
UploadURL string `json:"uploadUrl"`
AssetURL string `json:"assetUrl"`
Headers map[string]string `json:"headers"`
}
FileUploadResponse represents the response from the fileUpload mutation
type GraphQLError ¶
type GraphQLError struct {
Message string // The error message from GraphQL
Extensions map[string]interface{} // Additional error context from the API
}
GraphQLError represents an error returned by the Linear GraphQL API It includes the error message and any extensions provided by the API
func (*GraphQLError) Error ¶
func (e *GraphQLError) Error() string
Error implements the error interface for GraphQLError
type Issue ¶
type Issue struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
Description string `json:"description"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
Project *Project `json:"project,omitempty"`
Creator *User `json:"creator,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Parent *ParentIssue `json:"parent,omitempty"`
Children ChildrenNodes `json:"children,omitempty"`
Cycle *CycleReference `json:"cycle,omitempty"`
Labels *LabelConnection `json:"labels,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
Priority *int `json:"priority,omitempty"`
Estimate *float64 `json:"estimate,omitempty"`
DueDate *string `json:"dueDate,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
URL string `json:"url"`
// Attachment support
AttachmentCount int `json:"attachmentCount"` // Total number of attachments
HasAttachments bool `json:"hasAttachments"` // Computed: AttachmentCount > 0
Attachments *AttachmentConnection `json:"attachments,omitempty"`
Comments *CommentConnection `json:"comments,omitempty"`
}
Issue represents a Linear issue
func (*Issue) ToCompact ¶
func (i *Issue) ToCompact() IssueCompact
ToCompact converts a full Issue to IssueCompact
func (*Issue) ToMinimal ¶
func (i *Issue) ToMinimal() IssueMinimal
ToMinimal converts a full Issue to IssueMinimal
type IssueClient ¶
type IssueClient struct {
// contains filtered or unexported fields
}
IssueClient handles all issue-related operations for the Linear API. It uses the shared BaseClient for HTTP communication and focuses solely on issue management functionality.
func NewIssueClient ¶
func NewIssueClient(base *BaseClient) *IssueClient
NewIssueClient creates a new issue client with the provided base client
func (*IssueClient) AssignIssue ¶
func (ic *IssueClient) AssignIssue(issueID, assigneeID string) error
AssignIssue assigns or unassigns an issue to/from a user Why: Issue assignment is crucial for workload management. Passing an empty assigneeID unassigns the issue, providing flexibility in one method.
func (*IssueClient) BatchUpdateIssues ¶
func (ic *IssueClient) BatchUpdateIssues(issueIDs []string, update BatchIssueUpdate) (*BatchIssueUpdateResult, error)
BatchUpdateIssues updates multiple issues with the same changes Why: Bulk operations are common in issue management, such as moving multiple issues to a new state, assigning them to someone, or applying labels in bulk.
func (*IssueClient) CreateIssue ¶
func (ic *IssueClient) CreateIssue(title, description, teamID string) (*Issue, error)
CreateIssue creates a new issue in Linear Why: This is a core function for creating work items in Linear. It requires a team assignment and supports optional descriptions for detailed context.
func (*IssueClient) GetIssue ¶
func (ic *IssueClient) GetIssue(issueID string) (*Issue, error)
GetIssue retrieves a single issue by ID Why: This is the primary method for fetching detailed issue information. It automatically extracts metadata from the description for easy access.
func (*IssueClient) GetIssueSimplified ¶
func (ic *IssueClient) GetIssueSimplified(issueID string) (*Issue, error)
GetIssueSimplified retrieves a single issue by ID with reduced query complexity Why: The full GetIssue query can sometimes hit server complexity limits for issues with many children or complex data. This simplified version excludes children nodes to reduce query complexity.
func (*IssueClient) GetIssueWithBestContext ¶
func (ic *IssueClient) GetIssueWithBestContext(issueID string) (*Issue, error)
GetIssueWithBestContext retrieves an issue with the most appropriate context Why: This intelligently determines whether to fetch parent or project context based on the issue's actual relationships, avoiding unnecessary API calls.
func (*IssueClient) GetIssueWithFallback ¶
func (ic *IssueClient) GetIssueWithFallback(issueID string) (*Issue, error)
GetIssueWithFallback attempts to get an issue with full details, falling back to simplified query if the full query fails with a server error. Why: This provides resilience against server-side complexity limits while still attempting to get full data when possible.
func (*IssueClient) GetIssueWithParentContext ¶
func (ic *IssueClient) GetIssueWithParentContext(issueID string) (*Issue, error)
GetIssueWithParentContext retrieves an issue with parent issue details Why: Understanding issue hierarchy is important for sub-tasks. This method provides parent context needed for proper sub-task management.
func (*IssueClient) GetIssueWithProjectContext ¶
func (ic *IssueClient) GetIssueWithProjectContext(issueID string) (*Issue, error)
GetIssueWithProjectContext retrieves an issue with additional project information Why: When working within a project context, we need more project details like metadata and state. This method provides that extended information in one call.
func (*IssueClient) GetIssueWithRelations ¶
func (ic *IssueClient) GetIssueWithRelations(issueID string) (*IssueWithRelations, error)
GetIssueWithRelations retrieves an issue with its blocking/blocked-by relations for dependency graph visualization.
func (*IssueClient) GetSubIssues ¶
func (ic *IssueClient) GetSubIssues(parentIssueID string) ([]SubIssue, error)
GetSubIssues retrieves all sub-issues for a given parent issue Why: Sub-task management requires fetching all children of an issue. This dedicated method provides that functionality efficiently.
func (*IssueClient) GetTeamIssuesWithRelations ¶
func (ic *IssueClient) GetTeamIssuesWithRelations(teamID string, limit int) ([]IssueWithRelations, error)
GetTeamIssuesWithRelations retrieves all issues for a team with their relations for building a complete dependency graph.
func (*IssueClient) ListAllIssues ¶
func (ic *IssueClient) ListAllIssues(filter *IssueFilter) (*ListAllIssuesResult, error)
ListAllIssues retrieves issues with comprehensive filtering, pagination, and sorting options Why: Users need flexible ways to query issues across teams, projects, states, etc. This method provides a powerful search interface with metadata support.
func (*IssueClient) ListAssignedIssues ¶
func (ic *IssueClient) ListAssignedIssues(limit int) ([]Issue, error)
ListAssignedIssues retrieves issues assigned to the authenticated user Why: Users need to see their workload. This method provides a focused view of assigned work with configurable result limits.
func (*IssueClient) ListIssueAttachments ¶
func (ic *IssueClient) ListIssueAttachments(issueID string) ([]Attachment, error)
ListIssueAttachments retrieves all attachments for a specific issue Why: Agents need to access UI specs, mockups, and screenshots attached to issues for implementation guidance. This method provides comprehensive attachment metadata including filename, size, content type, and URLs.
func (*IssueClient) RemoveIssueMetadataKey ¶
func (ic *IssueClient) RemoveIssueMetadataKey(issueID, key string) error
RemoveIssueMetadataKey removes a specific metadata key from an issue Why: Sometimes metadata keys become obsolete or need to be cleaned up. This method provides that capability without affecting other metadata.
func (*IssueClient) SearchIssuesEnhanced ¶
func (ic *IssueClient) SearchIssuesEnhanced(filters *IssueSearchFilters) (*IssueSearchResult, error)
SearchIssuesEnhanced searches for issues with advanced filtering options Why: Users need flexible search capabilities to find issues based on multiple criteria like team, state, labels, assignee, priority, and date ranges.
func (*IssueClient) UpdateIssue ¶
func (ic *IssueClient) UpdateIssue(issueID string, input UpdateIssueInput) (*Issue, error)
UpdateIssue updates an issue with the provided fields Why: Issues need to be updated with various fields like title, description, priority, etc. This method provides a flexible way to update any combination of fields while preserving existing data like metadata.
func (*IssueClient) UpdateIssueDescription ¶
func (ic *IssueClient) UpdateIssueDescription(issueID, newDescription string) error
UpdateIssueDescription updates an issue's description while preserving metadata Why: Descriptions may contain both user content and hidden metadata. This method ensures metadata is preserved when users update descriptions.
func (*IssueClient) UpdateIssueMetadataKey ¶
func (ic *IssueClient) UpdateIssueMetadataKey(issueID, key string, value interface{}) error
UpdateIssueMetadataKey updates a specific metadata key for an issue Why: Granular metadata updates are more efficient than replacing all metadata. This method allows updating individual keys without affecting others.
func (*IssueClient) UpdateIssueState ¶
func (ic *IssueClient) UpdateIssueState(issueID, stateID string) error
UpdateIssueState updates the workflow state of an issue Why: Moving issues through workflow states is a core project management action. This method provides that capability with proper validation.
type IssueCompact ¶
type IssueCompact struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
Assignee *User `json:"assignee,omitempty"`
Priority *int `json:"priority,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
Parent *struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
} `json:"parent,omitempty"`
Children []struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
} `json:"children,omitempty"`
}
IssueCompact represents a compact issue with commonly needed fields (~150 tokens) Use this when you need more context than minimal but not full details
type IssueConnection ¶
type IssueConnection struct {
Nodes []ProjectIssue `json:"nodes"`
}
IssueConnection represents the GraphQL connection for issues
type IssueFilter ¶
type IssueFilter struct {
// Pagination
First int `json:"first"` // Number of items to fetch (required, max 250)
After string `json:"after,omitempty"` // Cursor for pagination
// Filters
StateIDs []string `json:"stateIds,omitempty"` // Filter by workflow state IDs
AssigneeID string `json:"assigneeId,omitempty"` // Filter by assignee user ID
LabelIDs []string `json:"labelIds,omitempty"` // Filter by label IDs
ProjectID string `json:"projectId,omitempty"` // Filter by project ID
TeamID string `json:"teamId,omitempty"` // Filter by team ID
// Sorting
OrderBy string `json:"orderBy,omitempty"` // Sort field: "createdAt", "updatedAt", "priority"
Direction string `json:"direction,omitempty"` // Sort direction: "asc" or "desc"
// Response format (minimal, compact, or full)
Format ResponseFormat `json:"format,omitempty"`
}
IssueFilter represents filter options for listing issues
type IssueMinimal ¶
type IssueMinimal struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
ParentIdentifier string `json:"parentIdentifier,omitempty"` // Parent issue identifier (e.g., "CEN-123")
}
IssueMinimal represents a minimal issue with only essential fields (~50 tokens) Use this for efficient browsing and list operations where full details aren't needed
type IssueRelation ¶
type IssueRelation struct {
ID string `json:"id"`
Type IssueRelationType `json:"type"`
Issue *IssueMinimal `json:"issue"`
RelatedIssue *IssueMinimal `json:"relatedIssue"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
IssueRelation represents a dependency relationship between two issues
type IssueRelationConnection ¶
type IssueRelationConnection struct {
Nodes []IssueRelation `json:"nodes"`
}
IssueRelationConnection represents a collection of issue relations
type IssueRelationType ¶
type IssueRelationType string
IssueRelationType represents the type of relationship between issues
const ( // RelationBlocks indicates this issue blocks another RelationBlocks IssueRelationType = "blocks" // RelationDuplicate indicates this issue is a duplicate RelationDuplicate IssueRelationType = "duplicate" // RelationRelated indicates a general relationship RelationRelated IssueRelationType = "related" )
type IssueSearchFilters ¶
type IssueSearchFilters struct {
// Team filter
TeamID string `json:"teamId,omitempty"`
// Identifier filter (e.g., "CEN-123")
Identifier string `json:"identifier,omitempty"`
// State filters
StateIDs []string `json:"stateIds,omitempty"`
// Label filters
LabelIDs []string `json:"labelIds,omitempty"`
// Assignee filter
AssigneeID string `json:"assigneeId,omitempty"`
// Cycle filter
CycleID string `json:"cycleId,omitempty"`
// Priority filter (0-4, where 0 is no priority, 1 is urgent, 4 is low)
Priority *int `json:"priority,omitempty"`
// Text search
SearchTerm string `json:"searchTerm,omitempty"`
// Include archived issues
IncludeArchived bool `json:"includeArchived,omitempty"`
// Date filters
CreatedAfter string `json:"createdAfter,omitempty"`
CreatedBefore string `json:"createdBefore,omitempty"`
UpdatedAfter string `json:"updatedAfter,omitempty"`
UpdatedBefore string `json:"updatedBefore,omitempty"`
// Pagination
Limit int `json:"limit"`
After string `json:"after,omitempty"`
// Response format (minimal, compact, or full)
Format ResponseFormat `json:"format,omitempty"`
}
IssueSearchFilters represents enhanced filter options for searching issues
type IssueSearchResult ¶
type IssueSearchResult struct {
Issues []Issue `json:"issues"`
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
}
IssueSearchResult represents the result of searching issues with pagination
type IssueWithDetails ¶
type IssueWithDetails struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
Description string `json:"description"`
Priority int `json:"priority"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
State WorkflowState `json:"state"`
Assignee *User `json:"assignee,omitempty"`
Labels []Label `json:"labels"`
Project *Project `json:"project,omitempty"`
Team Team `json:"team"`
Metadata *map[string]interface{} `json:"metadata,omitempty"`
}
IssueWithDetails represents an issue with full details including metadata
type IssueWithRelations ¶
type IssueWithRelations struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
Relations IssueRelationConnection `json:"relations"`
InverseRelations IssueRelationConnection `json:"inverseRelations"`
}
IssueWithRelations extends Issue with relation information
type Label ¶
type Label struct {
ID string `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
Description string `json:"description"`
}
Label represents a Linear label
type LabelConnection ¶
type LabelConnection struct {
Nodes []Label `json:"nodes"`
}
LabelConnection represents a connection to labels
type ListAllIssuesResult ¶
type ListAllIssuesResult struct {
Issues []IssueWithDetails `json:"issues"`
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
TotalCount int `json:"totalCount"`
}
ListAllIssuesResult represents the result of listing all issues
type ListUsersResult ¶
type ListUsersResult struct {
Users []User `json:"users"`
HasNextPage bool `json:"hasNextPage"`
EndCursor string `json:"endCursor"`
}
ListUsersResult represents the result of listing users with pagination
type NotFoundError ¶
type NotFoundError struct {
ResourceType string // Type of resource (e.g., "issue", "project", "user")
ResourceID string // ID of the resource that wasn't found
}
NotFoundError represents a resource not found error It indicates that a requested resource doesn't exist
func (*NotFoundError) Error ¶
func (e *NotFoundError) Error() string
Error implements the error interface for NotFoundError
type Notification ¶
type Notification struct {
ID string `json:"id"`
Type string `json:"type"`
CreatedAt string `json:"createdAt"`
ReadAt *string `json:"readAt,omitempty"`
ArchivedAt *string `json:"archivedAt,omitempty"`
SnoozedUntilAt *string `json:"snoozedUntilAt,omitempty"`
User *User `json:"user,omitempty"`
Issue *NotificationIssue `json:"issue,omitempty"`
Comment *NotificationComment `json:"comment,omitempty"`
}
Notification represents a Linear notification
type NotificationClient ¶
type NotificationClient struct {
// contains filtered or unexported fields
}
NotificationClient handles all notification-related operations for the Linear API. It uses the shared BaseClient for HTTP communication and manages user notifications including mentions and updates.
func NewNotificationClient ¶
func NewNotificationClient(base *BaseClient) *NotificationClient
NewNotificationClient creates a new notification client with the provided base client
func (*NotificationClient) GetNotifications ¶
func (nc *NotificationClient) GetNotifications(includeRead bool, limit int) ([]Notification, error)
GetNotifications retrieves notifications for the authenticated user Why: Notifications keep users informed about mentions, assignments, and updates. This method provides access to that activity stream.
func (*NotificationClient) MarkNotificationRead ¶
func (nc *NotificationClient) MarkNotificationRead(notificationID string) error
MarkNotificationRead marks a notification as read Why: Users need to acknowledge notifications to keep their inbox manageable. This method provides that acknowledgment capability.
type NotificationComment ¶
NotificationComment represents comment info in a notification
type NotificationIssue ¶
type NotificationIssue struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
}
NotificationIssue represents issue info in a notification
type PaginationInput ¶
type PaginationInput struct {
Start int `json:"start"` // Starting position (0-indexed)
Limit int `json:"limit"` // Number of items per page
Sort string `json:"sort"` // Sort field: priority|created|updated
Direction string `json:"direction"` // Sort direction: asc|desc
}
PaginationInput represents offset-based pagination parameters
func ValidatePagination ¶
func ValidatePagination(input *PaginationInput) *PaginationInput
ValidatePagination validates and normalizes pagination input
type ParentIssue ¶
type ParentIssue struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
Description string `json:"description"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
ParentIssue represents a parent issue
type Project ¶
type Project struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"` // Short description (255 char limit)
Content string `json:"content,omitempty"` // Long markdown content (no limit)
State string `json:"state"` // planned, started, completed, etc.
Issues *IssueConnection `json:"issues,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
Project represents a Linear project
func (*Project) GetIssues ¶
func (p *Project) GetIssues() []ProjectIssue
GetIssues returns the issues from a project, handling nil Issues field
type ProjectClient ¶
type ProjectClient struct {
// contains filtered or unexported fields
}
ProjectClient handles all project-related operations for the Linear API. It uses the shared BaseClient for HTTP communication and focuses on project management functionality.
func NewProjectClient ¶
func NewProjectClient(base *BaseClient) *ProjectClient
NewProjectClient creates a new project client with the provided base client
func (*ProjectClient) CreateProject ¶
func (pc *ProjectClient) CreateProject(name, description, teamID string) (*Project, error)
CreateProject creates a new project in Linear Why: Projects are containers for organizing related issues. This method enables project creation with proper team assignment.
func (*ProjectClient) GetProject ¶
func (pc *ProjectClient) GetProject(projectID string) (*Project, error)
GetProject retrieves a single project by ID Why: This is the primary method for fetching detailed project information including associated issues and metadata.
func (*ProjectClient) ListAllProjects ¶
func (pc *ProjectClient) ListAllProjects(limit int) ([]Project, error)
ListAllProjects retrieves all projects in the workspace Why: Users need to discover available projects. This method provides a complete list with optional limiting for performance.
func (*ProjectClient) ListUserProjects ¶
func (pc *ProjectClient) ListUserProjects(userID string, limit int) ([]Project, error)
ListUserProjects retrieves projects that have issues assigned to a specific user Why: Users often want to see only projects they're actively working on. This method filters projects based on issue assignments.
func (*ProjectClient) RemoveProjectMetadataKey ¶
func (pc *ProjectClient) RemoveProjectMetadataKey(projectID, key string) error
RemoveProjectMetadataKey removes a specific metadata key from a project Why: Metadata keys may become obsolete. This method allows selective removal without affecting other metadata. Note: Uses 'content' field instead of 'description' to avoid 255 char limit.
func (*ProjectClient) UpdateProject ¶
func (pc *ProjectClient) UpdateProject(projectID string, input UpdateProjectInput) (*Project, error)
UpdateProject updates a project with the provided input Supports updating name, description, state, lead, start date, and target date
func (*ProjectClient) UpdateProjectDescription ¶
func (pc *ProjectClient) UpdateProjectDescription(projectID, newContent string) error
UpdateProjectDescription updates a project's content while preserving metadata Why: Project content may contain both user content and metadata. This method ensures metadata is preserved during content updates. Note: Linear has two fields - 'description' (255 char limit) and 'content' (no limit). We use 'content' for longer text to avoid the character limit.
func (*ProjectClient) UpdateProjectMetadataKey ¶
func (pc *ProjectClient) UpdateProjectMetadataKey(projectID, key string, value interface{}) error
UpdateProjectMetadataKey updates a specific metadata key for a project Why: Granular metadata updates allow changing individual values without affecting other metadata. This is more efficient than full replacements. Note: Uses 'content' field instead of 'description' to avoid 255 char limit.
func (*ProjectClient) UpdateProjectState ¶
func (pc *ProjectClient) UpdateProjectState(projectID, state string) error
UpdateProjectState updates the state of a project Why: Projects have states (planned, started, completed, etc.) that need to be updated as work progresses. This method provides that capability.
type ProjectIssue ¶
type ProjectIssue struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
Assignee *User `json:"assignee,omitempty"`
}
ProjectIssue represents a minimal issue in a project context
type RateLimitError ¶
RateLimitError represents a rate limit error from the Linear API It includes information about when to retry the request
func (*RateLimitError) Error ¶
func (e *RateLimitError) Error() string
Error implements the error interface for RateLimitError
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 ¶
NewResolver creates a new resolver with the default cache TTL
func (*Resolver) ResolveCycle ¶
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 ¶
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) ResolveTeam ¶
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 ¶
ResolveUser resolves a user identifier (email or name) to a user UUID Supports: - Email addresses: "john@company.com" - Display names: "John Doe" - First names: "John" (errors if ambiguous)
Returns error with suggestions if multiple users match
type ResponseFormat ¶
type ResponseFormat string
ResponseFormat specifies the level of detail in API responses
const ( // FormatMinimal returns only essential fields (~50 tokens per issue) FormatMinimal ResponseFormat = "minimal" // FormatCompact returns commonly needed fields (~150 tokens per issue) FormatCompact ResponseFormat = "compact" // FormatFull returns all fields (~ 1500 tokens per issue) FormatFull ResponseFormat = "full" )
func ParseResponseFormat ¶
func ParseResponseFormat(s string) (ResponseFormat, error)
ParseResponseFormat parses a string into a ResponseFormat with validation
type SubIssue ¶
type SubIssue struct {
ID string `json:"id"`
Identifier string `json:"identifier"`
Title string `json:"title"`
State struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"state"`
}
SubIssue represents a minimal sub-issue with its state
type Team ¶
type Team struct {
ID string `json:"id"`
Name string `json:"name"`
Key string `json:"key"`
Description string `json:"description"`
IssueEstimationType string `json:"issueEstimationType,omitempty"` // notUsed, exponential, fibonacci, linear, tShirt
IssueEstimationAllowZero bool `json:"issueEstimationAllowZero,omitempty"` // Whether 0 is allowed as estimate
IssueEstimationExtended bool `json:"issueEstimationExtended,omitempty"` // Whether extended estimates are enabled
DefaultIssueEstimate *float64 `json:"defaultIssueEstimate,omitempty"` // Default estimate for new issues
}
Team represents a Linear team
func (*Team) GetEstimateScale ¶
func (t *Team) GetEstimateScale() *EstimateScale
GetEstimateScale returns the available estimate values based on team settings
type TeamClient ¶
type TeamClient struct {
// contains filtered or unexported fields
}
TeamClient handles all team and user-related operations for the Linear API. It uses the shared BaseClient for HTTP communication and focuses on organizational structure queries.
func NewTeamClient ¶
func NewTeamClient(base *BaseClient) *TeamClient
NewTeamClient creates a new team client with the provided base client
func (*TeamClient) GetTeam ¶
func (tc *TeamClient) GetTeam(teamID string) (*Team, error)
GetTeam retrieves a single team by ID with estimate settings Why: Users need to get details about a specific team including the estimate scale configuration for that team.
func (*TeamClient) GetTeams ¶
func (tc *TeamClient) GetTeams() ([]Team, error)
GetTeams retrieves all teams in the workspace Why: Teams are the primary organizational unit in Linear. Users need to discover available teams for issue creation and assignment.
func (*TeamClient) GetUser ¶
func (tc *TeamClient) GetUser(userID string) (*User, error)
GetUser retrieves a specific user by ID with optional team memberships and preferences Why: Users need to look up specific team members by their unique ID to view profile details, team associations, and notification preferences.
func (*TeamClient) GetUserByEmail ¶
func (tc *TeamClient) GetUserByEmail(email string) (*User, error)
GetUserByEmail retrieves a user by their email address Why: Email is a common identifier for users. This allows finding users when only their email is known, useful for mentions and assignments.
func (*TeamClient) GetViewer ¶
func (tc *TeamClient) GetViewer() (*User, error)
GetViewer retrieves information about the authenticated user Why: Users need to know their own identity and capabilities within the system. This is essential for determining permissions and context.
func (*TeamClient) ListLabels ¶
func (tc *TeamClient) ListLabels(teamID string) ([]Label, error)
ListLabels retrieves all labels for a specific team Why: Labels are used to categorize and filter issues. Teams need to discover available labels for issue tagging and organization.
func (*TeamClient) ListUsers ¶
func (tc *TeamClient) ListUsers(filter *UserFilter) ([]User, error)
ListUsers retrieves users based on the provided filter Why: Users need to discover team members, find assignees, and understand organizational structure. Filters allow focusing on specific subsets.
func (*TeamClient) ListUsersWithDisplayNameFilter ¶
func (tc *TeamClient) ListUsersWithDisplayNameFilter(displayName string, activeOnly *bool, limit int) ([]User, error)
ListUsersWithDisplayNameFilter retrieves users by displayName filter with optional active status Why: Efficient server-side filtering for user name resolution. Uses displayName filter to avoid downloading all users when searching by name.
func (*TeamClient) ListUsersWithPagination ¶
func (tc *TeamClient) ListUsersWithPagination(filter *UserFilter) (*ListUsersResult, error)
ListUsersWithPagination retrieves users with pagination information Why: Large organizations may have many users, requiring pagination to efficiently retrieve and display user lists.
type UpdateCycleInput ¶
type UpdateCycleInput struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
StartsAt *string `json:"startsAt,omitempty"`
EndsAt *string `json:"endsAt,omitempty"`
CompletedAt *string `json:"completedAt,omitempty"`
}
UpdateCycleInput represents the input for updating a cycle
type UpdateIssueInput ¶
type UpdateIssueInput struct {
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
Priority *int `json:"priority,omitempty"` // 0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low
Estimate *float64 `json:"estimate,omitempty"` // Story points estimate
DueDate *string `json:"dueDate,omitempty"` // ISO 8601 date format
StateID *string `json:"stateId,omitempty"` // Workflow state ID
AssigneeID *string `json:"assigneeId,omitempty"` // User ID to assign to
ProjectID *string `json:"projectId,omitempty"` // Project ID to move issue to
ParentID *string `json:"parentId,omitempty"` // Parent issue ID for sub-issues
TeamID *string `json:"teamId,omitempty"` // Team ID to move issue to
CycleID *string `json:"cycleId,omitempty"` // Cycle ID to move issue to
LabelIDs []string `json:"labelIds,omitempty"` // Label IDs to apply
}
UpdateIssueInput represents the input for updating an issue All fields are optional to support partial updates
type UpdateProjectInput ¶
type UpdateProjectInput struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Content *string `json:"content,omitempty"`
State *string `json:"state,omitempty"`
LeadID *string `json:"leadId,omitempty"`
StartDate *string `json:"startDate,omitempty"`
TargetDate *string `json:"targetDate,omitempty"`
}
UpdateProjectInput represents the input for updating a project
type User ¶
type User struct {
ID string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Email string `json:"email"`
AvatarURL string `json:"avatarUrl"`
Active bool `json:"active"`
Admin bool `json:"admin"`
CreatedAt string `json:"createdAt"`
IsMe bool `json:"isMe"`
Teams []Team `json:"teams,omitempty"`
}
User represents a Linear user with full information
func (*User) UnmarshalJSON ¶
UnmarshalJSON handles custom unmarshaling for User to support both direct teams array and nested teams.nodes structure from GraphQL
type UserFilter ¶
type UserFilter struct {
// Filter by team membership
TeamID string `json:"teamId,omitempty"`
// Filter by active status (nil means include all)
ActiveOnly *bool `json:"activeOnly,omitempty"`
// Pagination
First int `json:"first"` // Number of items to fetch (default 50, max 250)
After string `json:"after,omitempty"` // Cursor for pagination
}
UserFilter represents filter options for listing users
type ValidationError ¶
type ValidationError struct {
Field string // The field that failed validation
Value interface{} // The invalid value that was provided
Message string // Simple error message
Reason string // Why the validation failed
}
ValidationError represents an input validation failure It provides details about which field failed validation and why
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error implements the error interface for ValidationError
type WorkflowClient ¶
type WorkflowClient struct {
// contains filtered or unexported fields
}
WorkflowClient handles all workflow-related operations for the Linear API. It uses the shared BaseClient for HTTP communication and manages workflow states and transitions.
func NewWorkflowClient ¶
func NewWorkflowClient(base *BaseClient) *WorkflowClient
NewWorkflowClient creates a new workflow client with the provided base client
func (*WorkflowClient) GetWorkflowStateByName ¶
func (wc *WorkflowClient) GetWorkflowStateByName(teamID, stateName string) (*WorkflowState, error)
GetWorkflowStateByName retrieves a specific workflow state by name for a team Why: When updating issue states, users often know the state name (e.g., "In Progress") but need the state ID. This helper provides a convenient way to look up states by name. The search is case-insensitive to improve usability.
func (*WorkflowClient) GetWorkflowStates ¶
func (wc *WorkflowClient) GetWorkflowStates(teamID string) ([]WorkflowState, error)
GetWorkflowStates retrieves all available workflow states with caching Why: Understanding available workflow states is crucial for proper issue state management. This method provides all possible states an issue can transition to, optionally filtered by team. Results are cached per team to reduce API calls.
type WorkflowState ¶
type WorkflowState struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // backlog, unstarted, started, completed, canceled
Color string `json:"color"`
Position float64 `json:"position"`
Description string `json:"description"`
Team *Team `json:"team,omitempty"`
}
WorkflowState represents a workflow state in Linear
Source Files
¶
- attachment_client.go
- base_client.go
- client.go
- comment_client.go
- cycle_analytics.go
- cycle_client.go
- doc.go
- error_helpers.go
- errors.go
- http_client.go
- identifiers.go
- issue_client.go
- metadata.go
- notification_client.go
- pagination.go
- project_client.go
- resolver.go
- resolver_cache.go
- resolver_test_helpers.go
- team_client.go
- test_helpers.go
- types.go
- validation.go
- workflow_client.go
Directories
¶
| Path | Synopsis |
|---|---|
|
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. |