All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Release binaries for v2.2.0 (v2.2.0 release was created without build artifacts)
- Add
/v2suffix to Go module path (github.com/chainguard-sandbox/go-linear/v2) per Go major version requirements. Without this, pkg.go.dev cannot index v2.x releases. - Update all internal imports, ldflags, golangci-lint prefix, and documentation to use
/v2module path
- Update imports from
github.com/chainguard-sandbox/go-linear/...togithub.com/chainguard-sandbox/go-linear/v2/... - Update
go gettogo get github.com/chainguard-sandbox/go-linear/v2
- Sync upstream schema to
@linear/sdk@77.0.0(was 75.0.0) - Go 1.26.1 (was 1.25.7; fixes GO-2026-4596..4599 stdlib vulns)
- Added CODEOWNERS
- Bound
IssueUpdateNullableresponse body read to 10MB to prevent OOM - Validate HTTP status in
IssueUpdateNullablebefore parsing body - Route
IssueUpdateNullablethrough credential provider and auth normalization - Handle credential refresh failure instead of silently retrying with empty auth
- Correct
normalizeAuthHeaderlogic for short OAuth tokens - Handle malformed rate limit headers gracefully
- Guard
ResolveIssueagainst caching empty IDs from null API responses - Cache
ResolveUser("me")results to avoid repeated API calls - Use build version in UserAgent header
- Remove unused
ptrFloatfunction
- Added
step-security/harden-runnerto release workflow (was the only workflow missing it) - Quote shell variables in release workflow
- Bumped
github.com/modelcontextprotocol/go-sdkto 1.3.1 (CVE-2026-27896) - Bumped
github.com/njayp/ophisfrom 1.1.1 to 1.1.4 - Bumped
aquasecurity/trivy-actionfrom 0.34.0 to 0.35.0
- Drop Go 1.25 from test matrix (go.mod requires >= 1.26)
- Bump golangci-lint to v2.11 for Go 1.26 compatibility
- Clean up for public release
- JSON-only output: Dropped table output — all commands output JSON exclusively. The
--outputflag is removed (~4,000 lines removed). See docs/MIGRATION.md. - SDK:
IssueDelete(ctx, id)→IssueDelete(ctx, id, permanentlyDelete *bool). Passnilto preserve v1.x behavior.
Lifecycle Management (12 commands):
issue archive/issue unarchive/issue delete --permanentinitiative archive/initiative unarchive/initiative list-subproject archive/project unarchive/project milestone-list/project status-listteam unarchive/team remove-memberdocument unarchive
Resolver Improvements:
- Resolvers now show available options on "not found" errors (e.g., lists valid project statuses)
- Issue ID resolution added to
delete,archive, andunarchivecommands
Project Updates:
- Comprehensive
project updateflags for all mutable fields
Templates:
template getnow includestemplateDatafield showing pre-filled template valuesissue create --use-default-templateto apply the team's default template
CLI:
--versionflag with build metadata (version, commit, tree state, build date)--assignee=noneto unassign issues- Priority validation (0–4) across all commands
Error Handling:
- Structured error handling infrastructure with improved messages for fetch failures and empty input
- Sync upstream schema to
@linear/sdk@75.0.0 - Go 1.25.7 (fixes GO-2026-4337 TLS vulnerability)
- Removed goreleaser; simplified Makefile sync check
- Config-default labels no longer override template labels when
--labelis not explicitly passed - Resolve gosec findings: G704 (subprocess), G703 (error string), G117 (HTTP redirect), G706 (env var log sanitization)
- Skip ambiguous state name tests on multi-team workspaces
- Added
CONTRIBUTING.md - Added
docs/MIGRATION.mdfor v1→v2 upgrade guide - Removed static counts and outdated docs
- Bumped
step-security/harden-runner,actions/checkout,actions/setup-go,aquasecurity/trivy-action - Bumped
github.com/olekukonko/tablewriterand minor-and-patch dependency group
- Issue Resolution: Fixed
ResolveIssueusing fuzzy search instead of direct lookup, which could return wrong issues (e.g., "PSEC-78" returning PSEC-128). Now uses Linear'sissue(id:)query for exact identifier matching. Fixes #22. - Issue Update: Fixed
issue update --projectsilently failing when using project names instead of UUIDs. The command now properly resolves issue identifiers (e.g., ENG-123) to UUIDs before API calls. Fixes #20. - Name Resolution: Added consistent cycle and project name resolution across all issue commands (
update,create,batch-update). Previously these flags only accepted UUIDs, inconsistent with other fields like--assigneeand--statethat accept human-readable names.
Notification Inbox (3 commands):
notification list: View inbox notifications with filteringnotification get: Get notification detailsnotification unarchive: Restore archived notifications to inbox
AI Suggestions (1 command):
issue suggestions: View AI-recommended assignees, teams, labels, projects, and related issues
Comment Threading:
comment create --parent: Create threaded repliescomment get: Shows parent context and child replies with pagination (max 5000)
Issue Templates:
issue create --template: Apply templates during creation (title becomes optional)
Team Management (1 command):
team add-member: Add users to teams (admin required)
Total: 94 commands (was 89), 94 MCP tools
- Roadmap commands marked as deprecated (Linear deprecated in favor of initiatives)
- Migrate
multicachetofido(dependency renamed upstream)
- Fix broken test related to sub-second TTL in cache
- Fix concurrent cache race condition
- Request body size limiting (default 10MB, configurable via LINEAR_MAX_BODY_SIZE)
- Prevents OOM from bugs in query generation (hardening, not fixing exploitable vulnerability)
- Added
make modernizetarget for modern Go pattern analysis (min/max, range-int, etc.)
Status Updates (8 commands):
project status-update-{create,list,get,delete}: Track project progress with health indicatorsinitiative status-update-{create,list,get,archive}: Track initiative progress- Health states: onTrack, atRisk, offTrack
Team Metrics (1 command):
team velocity: Calculate performance from completed cycles (avg points/issues per cycle)
Command Enhancements:
initiative get: Accepts name or UUID; displays ID, status, health, target date, owner, parent initiative, linked projects (with progress), description, URLproject get: Accepts name or UUID; displays ID, progress, health, all dates (target/started/completed/canceled), lead, team(s), linked initiatives (with status), description, URLcycle get: Displays scope history and issue count metricsinitiative delete: Delete initiatives with confirmation
Name resolution in get commands simplifies workflows. Enhanced displays show strategic relationships and full context for weekly updates. All metrics from existing Linear API fields.
Initiative-Project Linking (2 commands):
initiative add-project: Link projects to strategic initiativesinitiative remove-project: Unlink projects from initiatives
Document Management (3 commands):
document create: Create knowledge base documents (requires --team, --project, --initiative, or --issue)document update: Modify document title and contentdocument delete: Remove documents with confirmation
Total: 89 commands (was 74), 89 MCP tools
- GraphQL queries updated with progress, health, and history fields for metrics
initiative create/update: Fixed field names (OwnerId→OwnerID), removed unsupported parent filtering, fixed status type castinginitiative get: Fixed description pointer handlinginitiative remove-project: Uses pagination to handle workspaces with 100+ links (prevents silent failures)
- Initiative delete command compilation errors
- Nil pointer checks in initiative and project commands
- Lint issues (nil checks, prealloc)
- Attachments: Fixed
attachment listcommand failure caused by JSONObject scalar mapping. Linear'ssourcefield returns native JSON objects (TypeScript behavior) but gqlgenc defaulted to string mapping. Now properly mapsJSONObjecttomap[string]interface{}in gqlgenc.yaml, preserving all source metadata (imageUrl, syncedCommentId, channelId, etc.). Fixes #14. - CLI: Fixed metadata flag parsing in
attachment createto properly convert JSON string to map.
- Tests: Comprehensive attachment integration tests with full lifecycle coverage (create, list, filter, get, delete) and all link types (URL, GitHub PR, Slack).
- Bump golang.org/x/sync from 0.17.0 to 0.19.0
New CLI layer: Introduced go-linear CLI between the SDK and MCP server. The CLI is context-engineered—it absorbs GraphQL complexity so agents (and humans) work at the semantic level.
v1.1.0: Agent → MCP → SDK → GraphQL
v1.2.0: Agent → MCP → CLI → SDK → GraphQL
The CLI operates at the right altitude—high enough to hide GraphQL mechanics, specific enough to express precise intent. This protects the agent's attention budget by absorbing:
- UUID resolution:
--team=ENGnot--team-id=abc-123-... - Field defaults: 8 fields returned, not 50+
- Pagination: Automatic, or
--countfor totals - Date parsing:
--created-after=7d - Batch operations: Update 50 issues in one call
MCP server auto-generated from CLI via ophis.
New semantic interface for humans and agents:
- Issue:
list,get,create,update,delete,search,batch-update,add-label,remove-label,relate,unrelate - Attachment:
list,get,create,delete,link-github,link-slack,link-url - Comment:
list,get,create,update,delete - Cycle:
list,get,create,update,archive - Project:
list,get,create,update,delete,milestone-create,milestone-update,milestone-delete - Team:
list,get,create,update,delete,members - User:
list,get,completed - Label:
list,get,create,update,delete - State:
list,get - Notification:
subscribe,unsubscribe,archive,update - Reaction:
create,delete - Favorite:
create,delete - Initiative:
list,get,create,update - Document/Roadmap/Template:
list,get - Utility:
viewer,organization,status
- Issue: SLA status, customer counts, AI suggestions, relationships, collections
- Cycle: 15 filters (active, past, future, date ranges)
- Project/Comment/Label/State/Team/User: 5-16 filters each
--fields=defaults(8 fields vs 50+)--countreturns{"count": N}(99% token reduction)Team.issueCountwithout pagination
ResolveCycle,ResolveDocument,ResolveInitiative,ResolveProject- Case-insensitive, fuzzy matching
- GitHub Actions release workflow (5 platforms)
- Performance profiling
- Multicache resolver for MCP persistence
- clog structured logging
- Claude skill (
.claude/skills/go-linear/SKILL.md) - SDK docs (
docs/SDK.md) - Filter docs (
docs/FILTERS.md) - Claude setup (
docs/CLAUDE-SETUP.md)
- MCP rebuilt: Now wraps CLI instead of SDK directly
- README: Rewritten with context engineering principles
- Client: Split into entity-focused files
- Resolver cache: synchronous writes
- Context cancellation
- Rate limit parsing
- Identifier resolution
- Nil safety across filter system
- Command coverage: 61-87%
- Filter tests: all 48 issue filters
- Internal packages: 60%+
- gosec and nilaway in CI
- Dependency updates
- @linear/sdk@68.1.0
1.1.0 - 2025-12-10
- Model Context Protocol (MCP) server for AI agent integration
- 13 tools exposing Linear API operations (viewer, teams, issues, search, comments, labels, workflow states, users)
- Read-only operations: 9 safe tools for querying Linear data
- Mutable operations: 4 tools (create_issue, update_issue, create_comment, delete_issue) with confirmation warnings
- JSON-RPC 2.0 over stdio following MCP specification
- Complete tool specifications in
mcp/tools.jsonwith safety markers - Automated test script in
mcp/test-mcp.sh - Example Go client in
examples/mcp-client/ - MCP server binary in
cmd/linear-mcp/with separate module
- JSON Schema for AI-friendly type discovery
- Complete schema definitions in
pkg/linear/schema.json - Embedded schema accessor:
linear.GetSchema() - Input/output types with validation rules and field constraints
- Complete schema definitions in
- AI Integration Documentation
- Complete MCP guide in
docs/MCP.mdwith setup, workflows, and safety details - Claude Desktop configuration instructions
- Linear API permission documentation (Read, Write, Admin, Create issues, Create comments)
- Permission detection via API responses (401 Unauthorized, 403 Forbidden)
- Complete MCP guide in
-
Improved variable naming in examples and documentation for clarity and consistency following Go best practices:
- Variables with
new*prefix (e.g.,newTitle,newName) renamed to more descriptive names usingupdated*prefix (e.g.,updatedTitle,updatedName) or context-specific names (e.g.,updatedTargetDate) unassignrenamed toemptyAssigneeto clarify its purposeaddedrenamed tolabelIDsToAddto be more explicit
Affected files:
- Documentation examples in
pkg/linear/client.go - Example programs in
examples/tasks/ - Test files in
pkg/linear/
Note: This is a documentation-only change. If you copied code from examples, update variable names to match the new patterns. The API itself is unchanged.
- Variables with
- MCP server includes safety warnings for all mutable operations
- Destructive operations (delete) marked with
x-dangerousandx-requires-confirmationflags - MCP server binary added to
.gitignore - All mutable tools require user confirmation with
⚠️ warnings in descriptions
1.0.0 - 2025-12-10
First stable release of go-linear, a production-ready Go client for the Linear API. This release marks API stability - future changes will follow semantic versioning.
- Comprehensive GraphQL client with 45+ methods covering Issues, Teams, Projects, Comments, Labels, Attachments, and more
- Type-safe GraphQL operations via genqlient
- Full CRUD operations for Issues, Comments, Labels, Teams, Projects, and Cycles
- Advanced operations: Issue relationships, attachments (URL, GitHub PR, Slack), reactions, favorites
- Search functionality with
SearchIssuesfor full-text search with filters
- Cursor-based pagination for all list operations
- Automatic pagination iterators (IssueIterator, TeamIterator, ProjectIterator, CommentIterator)
- Thread-safe iterators with mutex protection for concurrent access
- Redesigned iterator API returning values instead of pointers
- Automatic retry with exponential backoff and jitter
- Rate limit handling with Retry-After header support and monitoring callbacks
- Circuit breaker pattern for fail-fast during outages
- Bounded retry time prevents request hangs (default: 90s max)
- Request timeout support with context cancellation
- TLS configuration for security requirements (enforce TLS 1.2+)
- Dynamic credential management with auto-refresh on 401 errors
- HTTP connection pooling tuned for Linear rate limits
- Structured logging with log/slog integration
- Request ID correlation for incident tracking with Linear support
- Per-operation Prometheus metrics (not just generic "graphql" label)
- Request counts, duration histograms, error rates by operation
- Rate limit tracking (requests + complexity)
- Retry metrics by reason (rate_limited, server_error, network_error)
- Multi-tenancy support with instance-scoped metrics registries
- OpenTelemetry tracing support for distributed tracing
- Comprehensive API documentation with godoc comments
- 18 task-based examples for common operations
- Production deployment example with best practices
- Prometheus metrics integration example
- Error handling examples with retry patterns
- Operational runbook and monitoring guide
- Structured error types:
RateLimitError,AuthenticationError,ForbiddenError,LinearError - Error chain preservation for proper
errors.As()anderrors.Is()support - Improved GraphQL error extraction with operation context
- Helpful error messages with troubleshooting guidance
- All mutation input types exported (IssueCreateInput, TeamCreateInput, ProjectCreateInput, etc.)
- Clean public API with internal implementation details hidden
- Pointer fields for optional parameters (nil = omit or unchanged)
- 60%+ test coverage with mock and live integration tests
- Build tags for test isolation (read-only vs mutation tests)
- Race detection in all test runs
- Comprehensive transport layer tests
- Example tests for documentation validation
- Hardened GitHub Actions workflows (zizmor audit compliance)
- Credential isolation with
persist-credentials: false - Minimal token permissions with job-level grants
- Template injection prevention via environment variables
- Gitleaks secret scanning (pre-commit + CI)
- Dependabot for automated security updates
- Trivy and govulncheck for vulnerability scanning
- Comprehensive README with quick start, common tasks, and troubleshooting
- Production deployment guide with configuration options
- Operational runbook for incident response
- Monitoring guide with Prometheus queries and alerts
- Apache 2.0 license and security policy
- Agent-friendly documentation structure
- golangci-lint v2 with comprehensive linter configuration
- Pre-commit hooks for formatting, vetting, and linting
- CI workflows for testing, verification, and security scanning
- Upstream schema sync automation
- Automated dependency updates via Dependabot
- golangci-lint v2 migration and configuration compatibility
- Import ordering and code style issues
- Parameter type combinations for cleaner signatures
- HTTP test request bodies using
http.NoBody - Builtin shadowing in retry backoff calculation
- Deprecated
issueSearchreplaced withsearchIssues - Error chain wrapping for proper error type detection
- go.mod dependency classification (direct vs indirect)
- Client struct simplified with config separation
- Module paths standardized after fork
- Iterator API redesigned for better ergonomics
- Removed duplicate error types from internal package
- Example binaries from version control
- Unused transitive dependencies
API Stability: Starting with v1.0.0, this library follows semantic versioning:
- MAJOR version for incompatible API changes
- MINOR version for backwards-compatible functionality additions
- PATCH version for backwards-compatible bug fixes
Upstream Sync: GraphQL schema automatically synced from Linear TypeScript SDK
License: Apache 2.0