core

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: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetRetryAfter

func GetRetryAfter(err error) time.Duration

GetRetryAfter extracts the retry duration from a RateLimitError Returns 0 if the error is not a RateLimitError or has no retry duration

func GetSharedHTTPClient

func GetSharedHTTPClient() *http.Client

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 IsAuthenticationError

func IsAuthenticationError(err error) bool

IsAuthenticationError checks if an error is an AuthenticationError It uses errors.As to handle wrapped errors

func IsGraphQLError

func IsGraphQLError(err error) bool

IsGraphQLError checks if an error is a GraphQLError It uses errors.As to handle wrapped errors

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError checks if an error is a NotFoundError It uses errors.As to handle wrapped errors

func IsRateLimitError

func IsRateLimitError(err error) bool

IsRateLimitError checks if an error is a RateLimitError It uses errors.As to handle wrapped errors

func IsValidationError

func IsValidationError(err error) bool

IsValidationError checks if an error is a ValidationError It uses errors.As to handle wrapped errors

func NewOptimizedHTTPClient

func NewOptimizedHTTPClient() *http.Client

NewOptimizedHTTPClient creates an HTTP client optimized for Linear API usage

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

type AttachmentConnection

type AttachmentConnection struct {
	Nodes []Attachment `json:"nodes,omitempty"`
}

AttachmentConnection represents a paginated collection of attachments

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 {
	HTTPClient *http.Client // Exported for access from linear package
	// 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

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) ExecuteRequest

func (bc *BaseClient) ExecuteRequest(query string, variables map[string]interface{}, result interface{}) error

executeRequest is a helper method to execute GraphQL requests Why: All Linear API calls follow the same pattern - send GraphQL query, handle errors, decode response. This method centralizes that logic to avoid duplication and ensure consistent error handling.

func (*BaseClient) GetToken added in v1.6.0

func (bc *BaseClient) GetToken() (string, error)

GetToken returns the current access token for use in non-GraphQL authenticated requests.

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 ChildrenNodes

type ChildrenNodes struct {
	Nodes []SubIssue `json:"nodes"`
}

ChildrenNodes represents the children structure from GraphQL

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 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 CreateLabelInput added in v1.5.0

type CreateLabelInput struct {
	Name        string
	Color       string
	Description string
	TeamID      string // required — labels are team-scoped
	ParentID    string // optional — for sub-labels (groups)
}

CreateLabelInput represents the input for creating a label

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 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 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 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 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 HTTPError

type HTTPError struct {
	StatusCode int
	Body       string
}

HTTPError represents an HTTP-level error

func (*HTTPError) Error

func (e *HTTPError) Error() string

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"`
	Delegate  *User                  `json:"delegate,omitempty"` // Agent user delegated to work on issue (OAuth apps)
	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 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 IssueCreateInput added in v1.6.0

type IssueCreateInput struct {
	Title       string
	Description string
	TeamID      string
	AssigneeID  string
	CycleID     string
	DueDate     string
	Estimate    *float64
	LabelIDs    []string
	ParentID    string
	Priority    *int
	ProjectID   string
	StateID     string
}

IssueCreateInput represents the input for creating an issue atomically. All optional fields are resolved to UUIDs by the service layer before populating this struct.

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
	ExcludeLabelIDs []string `json:"excludeLabelIds,omitempty"` // Exclude issues with these 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"`

	// Project filter
	ProjectID string `json:"projectId,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"`
	ExcludeLabelIDs []string `json:"excludeLabelIds,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"`

	// Sorting
	OrderBy string `json:"orderBy,omitempty"` // Sort field: "createdAt", "updatedAt"

	// 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"`
	Project *struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	} `json:"project"`
	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 NotificationComment

type NotificationComment struct {
	ID   string `json:"id"`
	Body string `json:"body"`
}

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

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 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

type RateLimitError struct {
	RetryAfter time.Duration // How long to wait before retrying
}

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 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 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 (for human users)
	DelegateID  *string  `json:"delegateId,omitempty"` // Application ID to delegate to (for OAuth apps)
	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 UpdateLabelInput added in v1.5.0

type UpdateLabelInput struct {
	Name        *string
	Color       *string
	Description *string
	ParentID    *string
}

UpdateLabelInput represents the input for updating a label

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

func (u *User) UnmarshalJSON(data []byte) error

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 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

Jump to

Keyboard shortcuts

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