Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Documentation

on:
pull_request:
branches: [main]
paths: ["website/**", ".github/workflows/docs.yml"]
push:
branches: [main]
paths: ["website/**", ".github/workflows/docs.yml"]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: website/package-lock.json
- run: npm ci --prefix website
- run: npm run build --prefix website
- uses: actions/upload-artifact@v4
with:
name: website-build
path: website/build
if-no-files-found: error

deploy:
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: website-build
path: website/build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy website/build --project-name=linear-cli-docs --branch=main
- name: Smoke test production site
run: curl --fail --retry 5 --retry-delay 5 --retry-connrefused https://linear-cli.enolalab.com/
3 changes: 3 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.docusaurus/
build/
21 changes: 21 additions & 0 deletions website/docs/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Authentication

Commands use a Linear API key. Credential resolution is exact and ordered:

1. `--api-key <key>`
2. `LINEAR_API_KEY`
3. `api_key` in `~/.config/linear-cli/config.yaml`

The command flag wins over the environment; the environment wins over the config file.

```bash
LINEAR_API_KEY=lin_api_environment linear-cli team list
linear-cli --api-key lin_api_override team list
linear-cli auth login --token lin_api_saved
```

`auth login` writes `api_key` to the local config file. It requires `--token`; it does not prompt. `auth whoami` confirms the authenticated user. `user me` is an alias for `auth whoami`.

## Keep tokens out of command history

Prefer `LINEAR_API_KEY` from a process environment, secret manager, or CI secret. Avoid putting `--api-key` and `auth login --token` values directly in checked-in scripts, logs, or process listings. See [AI agents](./automation/ai-agents.md) for a safe invocation pattern.
40 changes: 40 additions & 0 deletions website/docs/automation/ai-agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# AI agents

`linear-cli` is designed for non-interactive shell execution: it does not request missing input, returns JSON, and uses categorized exit statuses. Agents should treat every invocation as an external side effect.

## Secure invocation pattern

Provide the key through a narrowly scoped environment variable supplied by the agent runtime or secret manager. Do not place a token in a prompt, argument list, repository file, or generated transcript.

```bash
env LINEAR_API_KEY="$LINEAR_API_KEY" linear-cli issue list --team ENG --limit 10
```

Avoid `set -x` around authenticated commands, redact captured command output before external logging, and do not use `--api-key` unless a controlled environment cannot supply `LINEAR_API_KEY`. Rotate a token exposed in a log or process listing.

## Read before write

Resolve identifiers and allowed values from Linear before making a mutation. For example, obtain workflow state IDs with `status list --team ENG`, then create or update an issue with a deliberate state value.

```bash
linear-cli status list --team ENG
linear-cli issue create --title "Triage incident" --team ENG --state "$STATE_ID"
```

Validate a mutation response before making a dependent mutation. Use `issue get` after a write when the workflow needs confirmation.

## Parse outcomes

Check the process status, then parse the JSON envelope. The exit code identifies the error category; `success` is the JSON equivalent. Retry only errors that make sense for the operation, such as a transient network failure or rate limit, with bounded backoff. Do not blindly retry writes after an ambiguous failure because the first request may have succeeded.

```bash
response=$(linear-cli issue search "login" --limit 5)
status=$?
if [ "$status" -ne 0 ]; then
printf '%s\n' "$response" >&2
exit "$status"
fi
printf '%s' "$response" | jq -r '.data[] | .identifier'
```

This CLI does not claim documented feature parity or a compatibility contract with Linear MCP. Agent integrations should use the command reference as the supported surface.
38 changes: 38 additions & 0 deletions website/docs/automation/shell-scripting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Shell scripting

Use compact JSON as the default transport between commands. `--pretty` is useful for inspection but not required for `jq`.

## Fail safely

```bash
#!/usr/bin/env bash
set -euo pipefail

: "${LINEAR_API_KEY:?Set LINEAR_API_KEY through your secret manager}"
issues=$(linear-cli issue list --team ENG --limit 20)
printf '%s' "$issues" | jq -r '.data[] | select(.priority == 1) | .identifier'
```

The CLI sends structured errors to standard output, so capture the response before deciding how to report it. Preserve the exit status; it has the categories documented in [output and errors](../output-and-errors.md).

## Iterate supported cursors

Only commands with a documented `--cursor` can advance a result set. This loop applies to `issue list`:

```bash
cursor=""
while :; do
args=(issue list --team ENG --limit 50)
if [ -n "$cursor" ]; then args+=(--cursor "$cursor"); fi
page=$(linear-cli "${args[@]}")
printf '%s\n' "$page" | jq -c '.data[]'
[ "$(printf '%s' "$page" | jq -r '.pagination.hasNextPage')" = true ] || break
cursor=$(printf '%s' "$page" | jq -r '.pagination.endCursor')
done
```

Do not use this pattern for `issue search`, `doc search`, or `label list`: they report pagination information but have no `--cursor` flag.

## File inputs

Use `--description-file` and `--body-file` for multiline markdown so shell quoting does not change the content. Use `attachment upload --file` for binary files; the command owns the presigned upload sequence.
25 changes: 25 additions & 0 deletions website/docs/commands/attachments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Attachments

## `attachment upload`

Upload a local file and link it to an issue. Both the issue identifier and file path are required.

```bash
linear-cli attachment upload --issue ENG-123 --file ./screenshot.png --title "Login failure"
```

| Flag | Required | Description |
| --- | --- | --- |
| `--issue <identifier>` | Yes | Issue identifier, such as `ENG-123` |
| `--file <path>` | Yes | Local file to upload |
| `--title <text>` | No | Attachment title; defaults to the filename |

## Presigned upload flow

The command reads the file, detects its MIME type from the extension or content, resolves the issue, and then:

1. Calls Linear's `fileUpload` mutation to request a presigned upload URL and asset URL.
2. Sends the local file with an HTTP `PUT` to that presigned URL, using a 60-second client timeout.
3. Calls `attachmentCreate` with the resolved issue ID, title, and asset URL.

The final `data` contains the created attachment, asset URL, file name, size, content type, and original issue identifier. The file data is sent to the presigned storage URL, not included in the JSON response.
23 changes: 23 additions & 0 deletions website/docs/commands/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Authentication commands

## `auth login`

Save an API key as `api_key` in the local configuration file.

```bash
linear-cli auth login --token lin_api_your_key
```

| Flag | Required | Description |
| --- | --- | --- |
| `--token <key>` | Yes | Linear API key to save |

## `auth whoami`

Fetch the authenticated viewer. The returned user includes `id`, `name`, `email`, `displayName`, `active`, and `admin`.

```bash
linear-cli auth whoami
```

See [authentication](../authentication.md) for resolution precedence.
27 changes: 27 additions & 0 deletions website/docs/commands/comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Comments

## `comment list`

List an issue's comments. The issue must be given as a `TEAM-NUMBER` identifier.

```bash
linear-cli comment list --issue ENG-123
```

| Flag | Required | Description |
| --- | --- | --- |
| `--issue <identifier>` | Yes | Issue identifier, such as `ENG-123` |

## `comment create`

Create a markdown comment. A body read from `--body-file` replaces `--body`.

```bash
linear-cli comment create --issue ENG-123 --body "Fixed in PR #456"
```

| Flag | Required | Description |
| --- | --- | --- |
| `--issue <identifier>` | Yes | Issue identifier |
| `--body <markdown>` | One body source | Comment body |
| `--body-file <path>` | One body source | Read the comment body from a file |
27 changes: 27 additions & 0 deletions website/docs/commands/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Configuration commands

## `config set <key> <value>`

Save a config value and return the key and value.

```bash
linear-cli config set default_team ENG
```

## `config get <key>`

Return a config value.

```bash
linear-cli config get default_team
```

## `config list`

Return all saved configuration. Saved `api_key` values are redacted.

```bash
linear-cli config list
```

The intended keys and `default_team` scope are documented in [configuration](../configuration.md).
23 changes: 23 additions & 0 deletions website/docs/commands/cycles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Cycles

## `cycle list`

List cycles (sprints) for a required team.

```bash
linear-cli cycle list --team ENG --limit 20 --cursor "$CURSOR"
```

| Flag | Default | Description |
| --- | ---: | --- |
| `--team <key>` | | Required team key |
| `--limit <n>` | 20 | Maximum result count |
| `--cursor <cursor>` | | Cursor from the previous response |

## `cycle get <cycle-id>`

Get a cycle and its issues.

```bash
linear-cli cycle get abc-123
```
30 changes: 30 additions & 0 deletions website/docs/commands/documents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Documents

## `doc list`

List workspace documents, including document content, project, creator, and timestamps.

```bash
linear-cli doc list --limit 20 --cursor "$CURSOR"
```

| Flag | Default | Description |
| --- | ---: | --- |
| `--limit <n>` | 20 | Maximum result count |
| `--cursor <cursor>` | | Cursor from the previous response |

## `doc get <doc-id>`

Get one document and full content.

```bash
linear-cli doc get abc-123
```

## `doc search <query>`

Search documents by text. It accepts `--limit <n>` (default 20). Although its response includes pagination metadata, it has no `--cursor` flag, so this CLI cannot retrieve later search pages.

```bash
linear-cli doc search "onboarding" --limit 5
```
28 changes: 28 additions & 0 deletions website/docs/commands/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Command reference

All commands inherit these root flags:

| Flag | Description |
| --- | --- |
| `--api-key <key>` | Linear API key; highest authentication precedence |
| `--pretty` | Pretty-print the JSON envelope |
| `--help` | Show Cobra help |

`linear-cli version` returns build metadata: `version`, `commit`, and `date`.

| Command group | Operations |
| --- | --- |
| `auth` | `login`, `whoami` |
| `config` | `set`, `get`, `list` |
| `team` | `list`, `get` |
| `user` | `list`, `get`, `me` |
| `issue` | `list`, `get`, `create`, `update`, `search` |
| `comment` | `list`, `create` |
| `label` | `list`, `create` |
| `status` | `list`, `get` |
| `project` | `list`, `get`, `create`, `update` |
| `cycle` | `list`, `get` |
| `doc` | `list`, `get`, `search` |
| `attachment` | `upload` |

Cobra also provides `completion` and `help`; they are framework commands rather than Linear resource operations.
Loading
Loading