lin

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT

README

lin

CI Release Go Reference Go version

The Linear CLI in Go: a single, fast, native binary that is first-class for both humans and AI agents, covering the Linear GraphQL API comprehensively.

lin is the token-based, scriptable Linear surface for headless / cron runs. JSON-first, agent-friendly, open-source quality from day one. Read VISION.md for the design principles and non-goals.

Install

go install github.com/alexgrais/lin/cmd/lin@latest
# or from a clone:
go build -o bin/lin ./cmd/lin

Authentication

lin authenticates with a Linear personal API key (lin_api_...), never via flags:

export LINEAR_API_KEY=lin_api_...          # 1. environment variable, or
export LINEAR_API_KEY_FILE=~/.secrets/lin  # 2. file containing the key, or
# 3. config file (must be chmod 600):
mkdir -p ~/.config/lin
printf '{"api_key": "lin_api_..."}' > ~/.config/lin/config.json && chmod 600 ~/.config/lin/config.json

Verify with lin whoami.

Usage

Resource-first grammar: lin <resource> <verb>. JSON on stdout, messages on stderr.

lin issue create --team ENG --title "Fix login" --labels bug --assignee me
lin issue list --team ENG --state "In Progress" --fields identifier,title --output table
lin issue update ENG-123 --state Done --add-labels regression
lin project get "Mobile app v2"                  # includes lead + milestones
lin attachment add ENG-123 ./screenshot.png      # 3-step upload dance, returns markdown embed
lin comment add ENG-123 --body "Deployed to staging"
lin describe                                     # full machine-readable command surface

Resources: issue (relations, sub-issues), comment, label, team, state, project, project-label, milestone, initiative, initiative-label, cycle, user, status-update, document, attachment, release, release-note, release-pipeline, customer, customer-need, plus whoami, version, describe.

The contract
  • --output json|ndjson|table (default json, regardless of TTY), --fields id,title masking
  • --dry-run on every mutation: prints {operation, variables} as they would go on the wire, resolves references, never executes the mutation
  • --json '{...}' raw payload on create/update commands (- reads stdin), 1:1 with the GraphQL input types, unknown fields rejected
  • Cursor pagination on every list: --limit, --cursor, --all; next_cursor in output
  • Destructive commands require --confirm=<id>
  • References accept human values: team key, me, emails, state/label/project names
Exit codes (sysexits)
Code Meaning
0 success
1 generic error
65 validation error (bad flags or input)
66 not found
70 internal error
75 temporary failure (rate limited, 5xx)
77 permission denied (check the API key)
78 configuration error (no API key)

Agents

lin describe returns the whole command surface as JSON - no help-text parsing needed. See AGENTS.md for the invariants agent consumers should load into context.

Development

go build -o bin/lin ./cmd/lin   # build
go test ./...                   # tests (mocked transport, no network)
golangci-lint run               # lint
go generate ./...               # regenerate the typed GraphQL client (genqlient)
go run ./tools/schema           # refresh the vendored Linear schema (ADR-0001)

See CONTRIBUTING.md to get set up, VISION.md for the design principles and non-goals, and SECURITY.md to report a vulnerability. Architecture decisions are recorded under docs/decisions/ (MADR). Releases follow the checklist in docs/RELEASING.md. If you are an AI agent driving lin, read AGENTS.md first.

Directories

Path Synopsis
cmd
lin command
Command lin is the Linear CLI entrypoint.
Command lin is the Linear CLI entrypoint.
internal
agent
Package agent owns the lin agent command group (Linear agent sessions, read surface).
Package agent owns the lin agent command group (Linear agent sessions, read surface).
attachment
Package attachment owns the lin attachment command group, including the 3-step fileUpload dance.
Package attachment owns the lin attachment command group, including the 3-step fileUpload dance.
audit
Package audit owns the lin audit command group (admin read of audit logs).
Package audit owns the lin audit command group (admin read of audit logs).
auth
Package auth owns the `lin auth` command group: storing, inspecting and switching Linear API keys held as named profiles in the XDG config file, so users stop re-exporting LINEAR_API_KEY and can manage several workspaces.
Package auth owns the `lin auth` command group: storing, inspecting and switching Linear API keys held as named profiles in the XDG config file, so users stop re-exporting LINEAR_API_KEY and can manage several workspaces.
cli
Package cli assembles the lin command tree: root, global flags, version and describe.
Package cli assembles the lin command tree: root, global flags, version and describe.
cmdutil
Package cmdutil carries the shared plumbing every resource command uses: the factory (IO + lazy GraphQL client), output option resolution, dry-run rendering, pagination flags, input hardening and raw JSON payload decoding.
Package cmdutil carries the shared plumbing every resource command uses: the factory (IO + lazy GraphQL client), output option resolution, dry-run rendering, pagination flags, input hardening and raw JSON payload decoding.
comment
Package comment owns the lin comment command group.
Package comment owns the lin comment command group.
config
Package config resolves the Linear API key and client settings.
Package config resolves the Linear API key and client settings.
customer
Package customer owns the lin customer and customer-need command groups.
Package customer owns the lin customer and customer-need command groups.
customview
Package customview owns the lin custom-view command group.
Package customview owns the lin custom-view command group.
cycle
Package cycle owns the lin cycle command group.
Package cycle owns the lin cycle command group.
document
Package document owns the lin document command group.
Package document owns the lin document command group.
emoji
Package emoji owns the lin emoji command group (custom workspace emojis).
Package emoji owns the lin emoji command group (custom workspace emojis).
externallink
Package externallink owns the lin external-link command group (entity external links on teams, projects, initiatives, cycles, releases).
Package externallink owns the lin external-link command group (entity external links on teams, projects, initiatives, cycles, releases).
favorite
Package favorite owns the lin favorite command group (viewer sidebar).
Package favorite owns the lin favorite command group (viewer sidebar).
gql
Package gql owns the GraphQL transport and the genqlient-generated typed client.
Package gql owns the GraphQL transport and the genqlient-generated typed client.
gql/gqltest
Package gqltest provides the fake GraphQL client every command test injects: it records calls and replays JSON fixtures, so no test ever touches the network.
Package gqltest provides the fake GraphQL client every command test injects: it records calls and replays JSON fixtures, so no test ever touches the network.
initiative
Package initiative owns the lin initiative and initiative-label groups.
Package initiative owns the lin initiative and initiative-label groups.
issue
Package issue owns the lin issue command group: CRUD, archive lifecycle, relations and list filters.
Package issue owns the lin issue command group: CRUD, archive lifecycle, relations and list filters.
label
Package label owns the lin label command group (issue labels).
Package label owns the lin label command group (issue labels).
lerr
Package lerr defines the error taxonomy mapped to sysexits codes at the CLI boundary.
Package lerr defines the error taxonomy mapped to sysexits codes at the CLI boundary.
milestone
Package milestone owns the lin milestone command group (project milestones).
Package milestone owns the lin milestone command group (project milestones).
notification
Package notification owns the lin notification command group (viewer inbox).
Package notification owns the lin notification command group (viewer inbox).
org
Package org owns the lin org command group (organization admin).
Package org owns the lin org command group (organization admin).
output
Package output renders command results.
Package output renders command results.
project
Package project owns the lin project and project-label command groups.
Package project owns the lin project and project-label command groups.
reaction
Package reaction owns the lin reaction command group.
Package reaction owns the lin reaction command group.
release
Package release owns the lin release, release-note and release-pipeline command groups.
Package release owns the lin release, release-note and release-pipeline command groups.
resolve
Package resolve turns human-friendly references (team key, user email, project/state/label names, issue identifiers) into the UUIDs the GraphQL mutations require.
Package resolve turns human-friendly references (team key, user email, project/state/label names, issue identifiers) into the UUIDs the GraphQL mutations require.
schedule
Package schedule owns the lin schedule command group (time schedules).
Package schedule owns the lin schedule command group (time schedules).
state
Package state owns the lin state command group (workflow states).
Package state owns the lin state command group (workflow states).
statusupdate
Package statusupdate owns the lin status-update command group.
Package statusupdate owns the lin status-update command group.
team
Package team owns the lin team command group.
Package team owns the lin team command group.
template
Package template owns the lin template command group.
Package template owns the lin template command group.
testutil
Package testutil hosts the command-level test harness: build a factory around the fake client, run a command line through the real root, capture stdout/stderr and the returned error.
Package testutil hosts the command-level test harness: build a factory around the fake client, run a command line through the real root, capture stdout/stderr and the returned error.
triage
Package triage owns the lin triage command group (triage responsibilities).
Package triage owns the lin triage command group (triage responsibilities).
user
Package user owns the lin user command group (read-only).
Package user owns the lin user command group (read-only).
viewer
Package viewer owns the whoami command (authenticated user).
Package viewer owns the whoami command (authenticated user).
webhook
Package webhook owns the lin webhook command group.
Package webhook owns the lin webhook command group.
tools
docsgen command
Command docsgen turns `lin describe` JSON (read from stdin) into an MDX command reference for the Fumadocs site: one page per top-level resource group, an index, and a reference page for exit codes and global flags.
Command docsgen turns `lin describe` JSON (read from stdin) into an MDX command reference for the Fumadocs site: one page per top-level resource group, an index, and a reference page for exit codes and global flags.
schema command
Command schema refreshes the vendored Linear GraphQL schema (internal/gql/schema.graphql) from the public linear/linear monorepo.
Command schema refreshes the vendored Linear GraphQL schema (internal/gql/schema.graphql) from the public linear/linear monorepo.
smokemock command
Command smokemock is a local stand-in for Linear's GraphQL API used by scripts/smoke-local.sh to drive the REAL lin binary end-to-end (process exit codes, auth header, upload PUT) without network or credentials.
Command smokemock is a local stand-in for Linear's GraphQL API used by scripts/smoke-local.sh to drive the REAL lin binary end-to-end (process exit codes, auth header, upload PUT) without network or credentials.

Jump to

Keyboard shortcuts

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