cli

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

Documentation

Overview

Package cli implements the command-line interface for the Linear CLI.

Architecture

The CLI is built using the Cobra framework and follows a modular command structure.

The root command is defined in root.go, which serves as the entry point and coordinates all subcommands. Each major entity (issues, cycles, projects, etc.) has its own file:

  • root.go - Root command and global flags (entry point)
  • auth.go - Authentication commands (login, logout, status)
  • issues.go - Issue management (list, get, create, update, comment, link)
  • cycles.go - Cycle operations (list, get, analyze)
  • projects.go - Project management (list, get, create, update)
  • search.go - Unified search across entities with dependency filtering
  • deps.go - Dependency graph visualization
  • skills.go - Claude Code skill management
  • init.go - Team configuration
  • onboard.go - Setup status and quick start guide

Common Patterns

## Team Resolution

Commands that require team context follow a consistent resolution order:

  1. Explicit --team flag
  2. Default team from .linear.yaml (set via 'linear init')
  3. Error if neither is provided

Use GetDefaultTeam to retrieve the configured default team.

## Project Resolution

Commands that accept a --project flag follow a consistent resolution order:

  1. Explicit --project flag
  2. Default project from .linear.yaml (manually configured)
  3. No project filter (all projects shown)

Use GetDefaultProject to retrieve the configured default project.

## Limit Validation

All list commands support --limit flags with consistent validation:

  • Default: 25 results
  • Maximum: 250 results (Linear API limit)
  • Values <= 0 default to 25
  • Values > 250 return an error

Use [validateAndNormalizeLimit] for consistent validation.

## Error Handling

Standardized error messages are defined in errors.go:

  • ErrTeamRequired - For missing team context
  • Use errors.New() for constant messages (not fmt.Errorf)

## Flag Descriptions

Reusable flag descriptions are centralized in flags.go:

## Helpers

Common utilities in helpers.go:

  • [readStdin] - Read from stdin
  • [parseCommaSeparated] - Parse comma-separated values
  • [getDescriptionFromFlagOrStdin] - Get text from flag or stdin (use "-" for stdin)
  • [uploadAndAppendAttachments] - Upload files and generate markdown
  • [validateAndNormalizeLimit] - Validate --limit flags
  • [looksLikeCycleNumber] - Detect numeric cycle IDs

Dependency Management

The search command supports powerful dependency filtering:

  • --blocked-by ID - Find issues blocked by a specific issue
  • --blocks ID - Find issues blocking a specific issue
  • --has-blockers - Find all blocked issues
  • --has-dependencies - Find issues with prerequisites
  • --has-circular-deps - Detect circular dependency chains
  • --max-depth N - Filter by dependency chain depth

The deps command visualizes dependency graphs using Mermaid syntax.

Service Layer

Commands interact with Linear via the service layer (internal/service):

  • IssueService - Issue operations
  • CycleService - Cycle analytics and retrieval
  • ProjectService - Project management
  • SearchService - Unified search with dependency filters
  • DepsService - Dependency graph analysis
  • UserService - User resolution (name/email → ID)

Services are obtained via helper functions:

  • [getLinearClient]
  • [getIssueService]
  • [getCycleService]
  • [getProjectService]
  • [getSearchService]
  • [getDepsService]
  • [getUserService]

State Management

The CLI is stateless between invocations. Each command:

  1. Creates a fresh linear.Client from stored OAuth tokens
  2. Constructs service layer instances as needed
  3. Executes the operation
  4. Exits

State persisted between runs:

  • OAuth tokens (via token.Storage in ~/.linear/)
  • Team and project defaults (via ConfigManager in .linear.yaml)

Configuration

Team defaults are stored in .linear.yaml via ConfigManager. OAuth tokens are stored securely via token.Storage.

Testing

Each command file has corresponding tests in *_test.go. See test files for examples of command validation and flag parsing.

Index

Constants

View Source
const (
	// TeamFlagDescription is the standard description for the --team flag
	TeamFlagDescription = "Team ID or key (uses .linear.yaml default)"

	// ProjectFlagDescription is the standard description for the --project flag
	ProjectFlagDescription = "Project name or UUID (uses .linear.yaml default)"
)

Flag descriptions - centralized to ensure consistency across commands

View Source
const (
	// DefaultLimit is the default number of results to return
	DefaultLimit = 25
	// MaxLimit is the maximum number of results allowed by the Linear API
	MaxLimit = 250
)
View Source
const (
	// ErrTeamRequired is returned when a team is required but not provided
	ErrTeamRequired = "--team is required (or run 'linear init' to set a default)"
)

Standard error messages

Variables

View Source
var (

	// Version is set via ldflags at build time
	Version = "dev"
)

Functions

func Execute

func Execute()

Execute runs the CLI with dependency injection

func GetDefaultProject added in v1.5.0

func GetDefaultProject() string

GetDefaultProject returns the default project from config, or empty string

func GetDefaultTeam

func GetDefaultTeam() string

GetDefaultTeam returns the default team from config, or empty string

func NewCmdWithDeps added in v1.3.0

func NewCmdWithDeps(deps *Dependencies, cmdFactory func() *cobra.Command) *cobra.Command

NewCmdWithDeps creates a command with dependencies injected for testing This allows tests to provide mock dependencies

func NewRootCmd

func NewRootCmd() *cobra.Command

NewRootCmd creates the root command for the 'linear' CLI

func NewTestClient added in v1.3.0

func NewTestClient(token string) *linear.Client

NewTestClient creates a Linear client with a test token Use this with a mock server for integration tests

func ResolutionError

func ResolutionError(resourceType, value, specificCommand string) error

ResolutionError creates a standard error message when auto-resolution fails

Types

type DepEdge

type DepEdge struct {
	From string // blocks
	To   string // is blocked by
	Type string
}

DepEdge represents a directed edge (dependency) in the graph

type DepNode

type DepNode struct {
	ID         string
	Identifier string
	Title      string
	State      string
}

DepNode represents a node in the dependency graph

type Dependencies added in v1.3.0

type Dependencies struct {
	// Client is the Linear API client
	Client *linear.Client

	// Services provide business logic and formatting
	Issues      service.IssueServiceInterface
	Cycles      service.CycleServiceInterface
	Projects    service.ProjectServiceInterface
	Search      service.SearchServiceInterface
	Teams       service.TeamServiceInterface
	Users       service.UserServiceInterface
	Labels      service.LabelServiceInterface
	TaskExport  service.TaskExportServiceInterface
	Attachments service.AttachmentServiceInterface
}

Dependencies holds all injectable dependencies for CLI commands This enables testing by allowing mock implementations to be injected

func NewDependencies added in v1.3.0

func NewDependencies(client *linear.Client) *Dependencies

NewDependencies creates dependencies with real implementations

func NewTestDependencies added in v1.3.0

func NewTestDependencies(client *linear.Client) *Dependencies

NewTestDependencies creates a Dependencies instance for testing Uses the provided client (which can be a mock or test client)

type DepsEdgeJSON added in v1.5.0

type DepsEdgeJSON struct {
	From string `json:"from"`
	To   string `json:"to"`
	Type string `json:"type"`
}

DepsEdgeJSON is the JSON representation of a dependency graph edge.

type DepsGraphJSON added in v1.5.0

type DepsGraphJSON struct {
	RootIssue string         `json:"rootIssue,omitempty"`
	Nodes     []DepsNodeJSON `json:"nodes"`
	Edges     []DepsEdgeJSON `json:"edges"`
	Cycles    [][]string     `json:"cycles"`
}

DepsGraphJSON is the JSON representation of a full dependency graph.

type DepsNodeJSON added in v1.5.0

type DepsNodeJSON struct {
	Identifier string `json:"identifier"`
	Title      string `json:"title"`
	State      string `json:"state"`
}

DepsNodeJSON is the JSON representation of a dependency graph node.

type IssueSearchOptions added in v1.3.0

type IssueSearchOptions struct {
	TextQuery     string
	Team          string
	Project       string
	State         string
	Priority      int
	Assignee      string
	Cycle         string
	Labels        string
	ExcludeLabels string
	BlockedBy     string
	Blocks        string
	HasBlockers   bool
	HasDeps       bool
	HasCircular   bool
	DepthMax      int
	Limit         int
	Format        string
	Output        string
}

IssueSearchOptions holds all parameters for issue search

type ProjectConfig

type ProjectConfig struct {
	Team    string `yaml:"team"`
	Project string `yaml:"project,omitempty"`
}

ProjectConfig represents the .linear.yaml config file

func LoadProjectConfig

func LoadProjectConfig() (*ProjectConfig, error)

LoadProjectConfig loads the .linear.yaml config from current or parent directories

Jump to

Keyboard shortcuts

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