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:
- Explicit --team flag
- Default team from .linear.yaml (set via 'linear init')
- 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:
- Explicit --project flag
- Default project from .linear.yaml (manually configured)
- 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:
- TeamFlagDescription - Standard team flag help text
## 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:
- Creates a fresh linear.Client from stored OAuth tokens
- Constructs service layer instances as needed
- Executes the operation
- 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
- Variables
- func Execute()
- func GetDefaultProject() string
- func GetDefaultTeam() string
- func NewCmdWithDeps(deps *Dependencies, cmdFactory func() *cobra.Command) *cobra.Command
- func NewRootCmd() *cobra.Command
- func NewTestClient(token string) *linear.Client
- func ResolutionError(resourceType, value, specificCommand string) error
- type DepEdge
- type DepNode
- type Dependencies
- type DepsEdgeJSON
- type DepsGraphJSON
- type DepsNodeJSON
- type IssueSearchOptions
- type ProjectConfig
Constants ¶
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
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 )
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 ¶
var (
// Version is set via ldflags at build time
Version = "dev"
)
Functions ¶
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 ¶
NewRootCmd creates the root command for the 'linear' CLI
func NewTestClient ¶ added in v1.3.0
NewTestClient creates a Linear client with a test token Use this with a mock server for integration tests
func ResolutionError ¶
ResolutionError creates a standard error message when auto-resolution fails
Types ¶
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 ¶
ProjectConfig represents the .linear.yaml config file
func LoadProjectConfig ¶
func LoadProjectConfig() (*ProjectConfig, error)
LoadProjectConfig loads the .linear.yaml config from current or parent directories