linear-sdk-cli 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/COVERAGE.md +14 -12
- package/README.md +94 -51
- package/package.json +2 -2
- package/skills/linear-sdk-cli/SKILL.md +9 -0
- package/skills/linear-sdk-cli/references/custom-view.md +205 -0
- package/src/cli.ts +2 -0
- package/src/commands/custom-view.ts +279 -0
- package/src/lib/json-input.ts +46 -0
- package/src/lib/options.ts +6 -0
- package/src/lib/output-shapes.ts +25 -0
- package/src/services/custom-view.ts +376 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ Release Please generates this file from Conventional Commits. Feature and fix pu
|
|
|
4
4
|
not edit it directly; their squash-commit titles are the release-note source of truth. This project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.4.0](https://github.com/zhendalf/linear-sdk-cli/compare/v0.3.3...v0.4.0) (2026-08-28)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- add custom view commands ([#38](https://github.com/zhendalf/linear-sdk-cli/issues/38)) ([fa99ae6](https://github.com/zhendalf/linear-sdk-cli/commit/fa99ae64ccbb23538bf53dc5fb8778e63ebd1b64))
|
|
12
|
+
|
|
13
|
+
## [0.3.3](https://github.com/zhendalf/linear-sdk-cli/compare/v0.3.2...v0.3.3) (2026-08-28)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- **deps:** publish @linear/sdk 92.0.0 upgrade ([eb7cb94](https://github.com/zhendalf/linear-sdk-cli/commit/eb7cb942a76ee810f1c79f614a369809258d2bc1))
|
|
18
|
+
|
|
7
19
|
## [0.3.2](https://github.com/zhendalf/linear-sdk-cli/compare/v0.3.1...v0.3.2) (2026-08-28)
|
|
8
20
|
|
|
9
21
|
### Bug Fixes
|
package/COVERAGE.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# SDK Coverage Audit
|
|
2
2
|
|
|
3
|
-
Generated by `bun run audit:coverage`. Total LinearClient members: **
|
|
3
|
+
Generated by `bun run audit:coverage`. Total LinearClient members: **472**.
|
|
4
4
|
|
|
5
5
|
| Status | Count | Meaning |
|
|
6
6
|
| -------- | ----- | ----------------------------------------------- |
|
|
7
|
-
| curated |
|
|
8
|
-
| raw-only |
|
|
9
|
-
| excluded |
|
|
7
|
+
| curated | 107 | Has a first-class CLI command |
|
|
8
|
+
| raw-only | 142 | Reachable via `linear api` (no bespoke command) |
|
|
9
|
+
| excluded | 223 | Out of scope (admin/integration/SDK plumbing) |
|
|
10
10
|
|
|
11
11
|
Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
12
12
|
100% reachable through the raw GraphQL escape hatch; they simply lack a tailored command.
|
|
13
13
|
|
|
14
|
-
## Curated (
|
|
14
|
+
## Curated (107)
|
|
15
15
|
|
|
16
16
|
- `agentSession` — issue
|
|
17
17
|
- `agentSessions` — issue
|
|
@@ -27,6 +27,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
27
27
|
- `comments` — comment
|
|
28
28
|
- `createAttachment` — attachment
|
|
29
29
|
- `createComment` — issue
|
|
30
|
+
- `createCustomView` — custom-view
|
|
30
31
|
- `createCycle` — cycle
|
|
31
32
|
- `createDocument` — document
|
|
32
33
|
- `createFavorite` — favorite
|
|
@@ -42,10 +43,13 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
42
43
|
- `createRoadmap` — roadmap
|
|
43
44
|
- `createTeam` — team
|
|
44
45
|
- `createWebhook` — webhook
|
|
46
|
+
- `customView` — custom-view
|
|
47
|
+
- `customViews` — custom-view
|
|
45
48
|
- `cycle` — cycle
|
|
46
49
|
- `cycles` — cycle
|
|
47
50
|
- `deleteAttachment` — attachment
|
|
48
51
|
- `deleteComment` — comment
|
|
52
|
+
- `deleteCustomView` — custom-view
|
|
49
53
|
- `deleteDocument` — document
|
|
50
54
|
- `deleteFavorite` — favorite
|
|
51
55
|
- `deleteInitiative` — initiative
|
|
@@ -96,6 +100,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
96
100
|
- `unarchiveInitiative` — initiative
|
|
97
101
|
- `unarchiveIssue` — issue
|
|
98
102
|
- `updateComment` — comment
|
|
103
|
+
- `updateCustomView` — custom-view
|
|
99
104
|
- `updateCycle` — cycle
|
|
100
105
|
- `updateDocument` — document
|
|
101
106
|
- `updateInitiative` — initiative
|
|
@@ -116,7 +121,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
116
121
|
- `workflowState` — state
|
|
117
122
|
- `workflowStates` — state
|
|
118
123
|
|
|
119
|
-
## Excluded (
|
|
124
|
+
## Excluded (223)
|
|
120
125
|
|
|
121
126
|
- `agentActivities` — specialized/raw api only
|
|
122
127
|
- `agentActivity` — specialized/raw api only
|
|
@@ -141,7 +146,6 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
141
146
|
- `createAgentSkill` — specialized/raw api only
|
|
142
147
|
- `createContact` — specialized/raw api only
|
|
143
148
|
- `createCsvExportReport` — specialized/raw api only
|
|
144
|
-
- `createCustomView` — specialized/raw api only
|
|
145
149
|
- `createCustomer` — specialized/raw api only
|
|
146
150
|
- `createCustomerNeed` — specialized/raw api only
|
|
147
151
|
- `createCustomerStatus` — specialized/raw api only
|
|
@@ -165,9 +169,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
165
169
|
- `createTimeSchedule` — specialized/raw api only
|
|
166
170
|
- `createTriageResponsibility` — specialized/raw api only
|
|
167
171
|
- `createViewPreferences` — specialized/raw api only
|
|
168
|
-
- `customView` — specialized/raw api only
|
|
169
172
|
- `customViewHasSubscribers` — specialized/raw api only
|
|
170
|
-
- `customViews` — specialized/raw api only
|
|
171
173
|
- `customer` — specialized/raw api only
|
|
172
174
|
- `customerMerge` — specialized/raw api only
|
|
173
175
|
- `customerNeed` — specialized/raw api only
|
|
@@ -181,7 +183,6 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
181
183
|
- `customerUpsert` — specialized/raw api only
|
|
182
184
|
- `customers` — specialized/raw api only
|
|
183
185
|
- `deleteAgentSkill` — specialized/raw api only
|
|
184
|
-
- `deleteCustomView` — specialized/raw api only
|
|
185
186
|
- `deleteCustomer` — specialized/raw api only
|
|
186
187
|
- `deleteCustomerNeed` — specialized/raw api only
|
|
187
188
|
- `deleteCustomerStatus` — specialized/raw api only
|
|
@@ -321,7 +322,6 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
321
322
|
- `unsuspendUser` — admin/enterprise (raw api only)
|
|
322
323
|
- `updateAgentSession` — specialized/raw api only
|
|
323
324
|
- `updateAgentSkill` — specialized/raw api only
|
|
324
|
-
- `updateCustomView` — specialized/raw api only
|
|
325
325
|
- `updateCustomer` — specialized/raw api only
|
|
326
326
|
- `updateCustomerNeed` — specialized/raw api only
|
|
327
327
|
- `updateCustomerStatus` — specialized/raw api only
|
|
@@ -347,7 +347,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
347
347
|
- `userRevokeSession` — admin/enterprise (raw api only)
|
|
348
348
|
- `userUnlinkFromIdentityProvider` — admin/enterprise (raw api only)
|
|
349
349
|
|
|
350
|
-
## Raw-only (
|
|
350
|
+
## Raw-only (142)
|
|
351
351
|
|
|
352
352
|
<details><summary>Show</summary>
|
|
353
353
|
|
|
@@ -486,6 +486,8 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
486
486
|
- `updateUserFlag`
|
|
487
487
|
- `updateUserSettings`
|
|
488
488
|
- `updateWorkflowState`
|
|
489
|
+
- `usageAlert`
|
|
490
|
+
- `usageAlerts`
|
|
489
491
|
- `userDiscordConnect`
|
|
490
492
|
- `userSessions`
|
|
491
493
|
- `userSettings`
|
package/README.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
[`@linear/sdk`](https://www.npmjs.com/package/@linear/sdk).**
|
|
5
5
|
|
|
6
6
|
It's designed to be pleasant for humans _and_ dependable for scripts and agents. By default you
|
|
7
|
-
get clean, aligned tables and detail views; add `--json` to any command for a stable,
|
|
7
|
+
get clean, aligned tables and detail views; add `--json` to any data command for a stable,
|
|
8
8
|
machine-readable shape. It's git-aware (the "current issue" comes from your branch name) and
|
|
9
9
|
forgiving about input (`--assignee me`, team key `TES`, state and label by name). Anything the
|
|
10
10
|
curated commands don't wrap is still reachable through a raw GraphQL escape hatch (`linear api`),
|
|
11
|
-
|
|
11
|
+
subject to the permissions granted to your Linear credential.
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
14
|
linear issue list --assignee me --state started # what's on my plate
|
|
@@ -19,6 +19,43 @@ linear issue list --json | jq -r '.[].identifier' # ready for scripts
|
|
|
19
19
|
> Design influenced by [`schpet/linear-cli`](https://github.com/schpet/linear-cli) (human-first,
|
|
20
20
|
> git-aware) and [`linearis`](https://github.com/linearis-oss/linearis) (JSON-first for agents).
|
|
21
21
|
|
|
22
|
+
## Why this project exists
|
|
23
|
+
|
|
24
|
+
This project grew from strong ideas in earlier tools, especially the human-first, git-aware
|
|
25
|
+
workflow credited above. Four requirements made a separate implementation the better fit for our
|
|
26
|
+
use case:
|
|
27
|
+
|
|
28
|
+
- **A smaller cloud deployment surface.** The reference implementation and its development path
|
|
29
|
+
centered on the full Deno runtime. Carrying that runtime into our cloud environments was more
|
|
30
|
+
infrastructure than the CLI warranted. This package ships its TypeScript source directly and
|
|
31
|
+
reuses the Bun runtime already present in our environment instead of packaging another runtime
|
|
32
|
+
for one tool. Later prebuilt releases moved that runtime into the artifact rather than
|
|
33
|
+
eliminating its footprint: for example, the
|
|
34
|
+
[v2.5.0 macOS ARM build](https://github.com/schpet/linear-cli/releases/tag/v2.5.0) expands to a
|
|
35
|
+
146 MB executable. Avoiding a heavyweight per-tool binary keeps cloud images and ephemeral agent
|
|
36
|
+
environments simpler and smaller.
|
|
37
|
+
- **Lower invocation overhead for agent loops.** An interactive CLI may start once; an agent can
|
|
38
|
+
start it dozens or hundreds of times while completing one workflow, so even modest cold-start
|
|
39
|
+
latency compounds. A public
|
|
40
|
+
[startup-time report](https://github.com/schpet/linear-cli/issues/261) documented the difference
|
|
41
|
+
against a compiled alternative and identified repeated agent calls as the motivating case. The
|
|
42
|
+
Bun-first implementation makes process startup a product constraint and reduces that recurring
|
|
43
|
+
overhead in our deployment model.
|
|
44
|
+
- **Alignment with Linear's official SDK.** The CLI is built directly on `@linear/sdk` and follows
|
|
45
|
+
its release cycle. Linear's SDK remains the source of truth for the API model, generated types,
|
|
46
|
+
connections, and transport; this project can focus on command design and stable output instead
|
|
47
|
+
of recreating official API machinery. A coverage audit catches additions, removals, and
|
|
48
|
+
classification drift among the SDK client's top-level members.
|
|
49
|
+
- **Agent-native development and maintenance.** This project was built from scratch by coding
|
|
50
|
+
agents, and agents continue to implement features, update dependencies, regenerate
|
|
51
|
+
documentation, run verification, and prepare maintenance and release work. Versioned maintenance
|
|
52
|
+
policy, CI, coverage checks, and release automation provide the guardrails that make that model
|
|
53
|
+
repeatable rather than ad hoc.
|
|
54
|
+
|
|
55
|
+
Together, those requirements made `linear-sdk-cli` the default for our deployments and automation
|
|
56
|
+
workflows. That is a statement about fit, not a claim that earlier tools are obsolete; this CLI
|
|
57
|
+
retains their best ideas and provides a careful compatibility and migration path.
|
|
58
|
+
|
|
22
59
|
## Highlights
|
|
23
60
|
|
|
24
61
|
- **Human-first by default** — aligned tables, rendered Markdown, safe paging for long detail,
|
|
@@ -32,8 +69,8 @@ linear issue list --json | jq -r '.[].identifier' # ready for scripts
|
|
|
32
69
|
|
|
33
70
|
## Install
|
|
34
71
|
|
|
35
|
-
Requires [Bun](https://bun.sh) **1.1 or newer
|
|
36
|
-
|
|
72
|
+
Requires [Bun](https://bun.sh) **1.1 or newer**. Authenticate with browser OAuth (the default), an
|
|
73
|
+
invocation-scoped OAuth access token, or a personal API key. The CLI ships as TypeScript and runs
|
|
37
74
|
directly on Bun — no build step, no bundle, no Node.
|
|
38
75
|
|
|
39
76
|
```sh
|
|
@@ -44,35 +81,12 @@ lin --help
|
|
|
44
81
|
This installs two equivalent binaries: **`linear`** and the shorter **`lin`**. If you already
|
|
45
82
|
have a different tool named `linear` on your `PATH`, just use `lin`.
|
|
46
83
|
|
|
47
|
-
###
|
|
48
|
-
|
|
49
|
-
Both CLIs install a binary called **`linear`**, so whichever is earlier on your `PATH` wins and
|
|
50
|
-
the other is silently shadowed — `linear --version` tells you which you got (`0.x` is this one,
|
|
51
|
-
`2.x` is schpet's), and `which -a linear` lists both. Three ways out, pick one:
|
|
52
|
-
|
|
53
|
-
- **Use `lin`.** It is ours alone; nothing of theirs claims it. Every example in this README works
|
|
54
|
-
with `lin` in place of `linear`. Zero-risk for the transition week.
|
|
55
|
-
- **Keep theirs reachable as `linear-schpet`** and let ours have `linear`:
|
|
56
|
-
|
|
57
|
-
```sh
|
|
58
|
-
# installed with deno: reinstall under a new name, then drop the old one
|
|
59
|
-
deno install -A --reload -f -g -n linear-schpet jsr:@schpet/linear-cli
|
|
60
|
-
deno uninstall -g linear
|
|
61
|
-
# installed with homebrew (schpet/tap/linear): keep the keg, relink under a new name
|
|
62
|
-
brew unlink schpet/tap/linear
|
|
63
|
-
ln -s "$(brew --prefix)/opt/linear/bin/linear" ~/.local/bin/linear-schpet # any dir on your PATH
|
|
64
|
-
# installed with npm/bun globally: rename the shim in place
|
|
65
|
-
mv "$(command -v linear)" "$(dirname "$(command -v linear)")/linear-schpet"
|
|
66
|
-
```
|
|
84
|
+
### Existing `linear` installations
|
|
67
85
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Their project-pinned install (`bun add -D @schpet/linear-cli`, run as `bunx linear`) does not
|
|
74
|
-
collide with a global install of ours; inside such a project `bunx linear` is theirs and
|
|
75
|
-
`linear`/`lin` on your `PATH` is ours.
|
|
86
|
+
Another CLI may already provide a binary named `linear`; whichever appears first on `PATH` wins.
|
|
87
|
+
Use this package's collision-free **`lin`** alias while evaluating or migrating. See
|
|
88
|
+
[`MIGRATING.md`](MIGRATING.md) for side-by-side installation, credential and config compatibility,
|
|
89
|
+
and the few commands whose behavior intentionally differs.
|
|
76
90
|
|
|
77
91
|
<details>
|
|
78
92
|
<summary>Run from source instead</summary>
|
|
@@ -88,7 +102,7 @@ bun run src/bin/linear.ts --help # or: bun run dev -- --help
|
|
|
88
102
|
## Quickstart
|
|
89
103
|
|
|
90
104
|
```sh
|
|
91
|
-
|
|
105
|
+
linear auth login # browser OAuth; or set LINEAR_API_KEY
|
|
92
106
|
linear whoami # confirm you're connected
|
|
93
107
|
|
|
94
108
|
linear issue list --assignee me --state started # my in-progress work
|
|
@@ -141,10 +155,10 @@ with `LINEAR_OAUTH_REDIRECT_URI`. No OAuth client secret is embedded, accepted,
|
|
|
141
155
|
|
|
142
156
|
For a personal API key, `auth login --key -` reads stdin, validates the viewer/workspace, stores the
|
|
143
157
|
key in the system keyring by default, and writes only a marker to the config. `--plaintext` is an
|
|
144
|
-
API-key-only compatibility option. API-key entries use `account = <workspace slug>`,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
158
|
+
API-key-only compatibility option. API-key entries use `account = <workspace slug>`, preserving
|
|
159
|
+
compatibility with existing keyring profiles. Passing a key as `--key <value>` works but warns
|
|
160
|
+
because argv is visible to other processes. `auth migrate` moves legacy plaintext keys into the
|
|
161
|
+
keyring, and `auth token` exports stored API keys only; OAuth tokens are never printed.
|
|
148
162
|
|
|
149
163
|
### Apps, agents, and service accounts
|
|
150
164
|
|
|
@@ -269,8 +283,8 @@ linear issue pr --json | jq -r .url # the created PR URL is the only thin
|
|
|
269
283
|
```
|
|
270
284
|
|
|
271
285
|
`issue describe` prints a whole commit message — `TES-123 Title`, a blank line, then two git
|
|
272
|
-
trailers, `Linear-issue: Fixes TES-123` and `Linear-issue-url: <url>` (
|
|
273
|
-
|
|
286
|
+
trailers, `Linear-issue: Fixes TES-123` and `Linear-issue-url: <url>` (compatible with existing
|
|
287
|
+
workflows, so `git interpret-trailers` and jj read it back). The magic word sits
|
|
274
288
|
right before the id, which is where Linear's
|
|
275
289
|
[git integration](https://linear.app/docs/github#link-prs-and-commits) reads it, so the issue is
|
|
276
290
|
linked — and closed on merge — when the commit lands; `-r` swaps in `References` to link without
|
|
@@ -306,6 +320,35 @@ Status updates (`project-update`/`pu`, `initiative-update`/`iu`) take the body f
|
|
|
306
320
|
`--body-file <path>` (`-` for stdin), or `--editor` (`$EDITOR`), plus an optional
|
|
307
321
|
`--health <onTrack|atRisk|offTrack>`.
|
|
308
322
|
|
|
323
|
+
**Custom views** — create and inspect saved Issue, Project, and Initiative filters without writing
|
|
324
|
+
GraphQL. A filter is the current Linear `IssueFilter`, `ProjectFilter`, or `InitiativeFilter` JSON
|
|
325
|
+
object; pass it inline or from a file/stdin. The selected `--type` decides which typed SDK input
|
|
326
|
+
field receives it, and an omitted filter becomes `{}` so the view type still round-trips.
|
|
327
|
+
|
|
328
|
+
```sh
|
|
329
|
+
linear custom-view list
|
|
330
|
+
linear cv create --name "Urgent" --type issue \
|
|
331
|
+
--filter '{"priority":{"eq":1}}' --shared
|
|
332
|
+
linear cv view 01234567-89ab-cdef-0123-456789abcdef
|
|
333
|
+
linear cv results 01234567-89ab-cdef-0123-456789abcdef --all
|
|
334
|
+
linear cv update 01234567-89ab-cdef-0123-456789abcdef \
|
|
335
|
+
--filter-file issue-filter.json --personal
|
|
336
|
+
linear cv delete 01234567-89ab-cdef-0123-456789abcdef --yes
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Create can attach a view with one of `--scope-team`, `--scope-project`, or `--scope-initiative`.
|
|
340
|
+
Linear marks project/initiative scope fields internal on update, so update exposes only the public
|
|
341
|
+
team scope (`--scope-team` / `--clear-team-scope`) and never rewrites an unspecified scope. View
|
|
342
|
+
references are UUID-only: names are not unique, and Linear's `customViews` query intentionally
|
|
343
|
+
omits project- and initiative-scoped views. Those scoped views remain accessible by UUID. Initiative
|
|
344
|
+
views require an eligible Linear plan.
|
|
345
|
+
|
|
346
|
+
```sh
|
|
347
|
+
linear cv list --json | jq -r '.[] | [.id, .name, .type] | @tsv'
|
|
348
|
+
linear cv results 01234567-89ab-cdef-0123-456789abcdef --json
|
|
349
|
+
# [{"type":"issue","id":"…","identifier":"ENG-42","name":"Fix login","url":"…"}]
|
|
350
|
+
```
|
|
351
|
+
|
|
309
352
|
## Command overview
|
|
310
353
|
|
|
311
354
|
Every group has `--help` with full options and (for the busy ones) an Examples section. Aliases
|
|
@@ -327,6 +370,7 @@ are shown in parentheses. For a machine-readable tree of _every_ command, run
|
|
|
327
370
|
| **`document`** (`doc`) | `list` · `view` · `create` · `update` · `delete` |
|
|
328
371
|
| **`attachment`** (`at`) | `list` · `create` · `delete` |
|
|
329
372
|
| **`favorite`** (`fav`) | `list` · `add` · `remove` |
|
|
373
|
+
| **`custom-view`** (`cv`) | `list` · `view` · `results` · `create` · `update` · `delete` |
|
|
330
374
|
| **`initiative`** (`init`) | `list` · `view` · `create` · `update` · `archive` · `delete` |
|
|
331
375
|
| **`initiative-update`** (`iu`) | `create` · `list` (initiative status updates, with `--health`) |
|
|
332
376
|
| **`roadmap`** (`rm`) | `list` · `view` · `create` · `update` · `delete` <sup>†</sup> |
|
|
@@ -458,15 +502,15 @@ versioned maintenance policy. See [`skills/README.md`](skills/README.md) for the
|
|
|
458
502
|
contract.
|
|
459
503
|
|
|
460
504
|
The CLI skill is self-contained: an agent that has only the skill and no CLI is told to
|
|
461
|
-
`bun add -g linear-sdk-cli`, and
|
|
462
|
-
|
|
463
|
-
gives it the full command surface at runtime, so the reference docs are a starting point,
|
|
464
|
-
cage.
|
|
505
|
+
`bun add -g linear-sdk-cli`, and a migrating user is told to check `linear auth status` before
|
|
506
|
+
re-entering a key because compatible credentials are discovered automatically. `linear commands
|
|
507
|
+
--json` gives it the full command surface at runtime, so the reference docs are a starting point,
|
|
508
|
+
not a cage.
|
|
465
509
|
|
|
466
510
|
## Coming from linear-cli
|
|
467
511
|
|
|
468
512
|
> The full guide — install without a collision, credentials found without a re-login, config
|
|
469
|
-
>
|
|
513
|
+
> compatibility, and the places where behavior intentionally differs — is
|
|
470
514
|
> [`MIGRATING.md`](MIGRATING.md). This section is the flag-level cheat sheet.
|
|
471
515
|
|
|
472
516
|
If your fingers or your scripts learned the other `linear-cli`, most of its spellings work here
|
|
@@ -524,12 +568,11 @@ Precedence, highest first — `linear config` prints each value with the tier an
|
|
|
524
568
|
1. the flag (`--team`, `--workspace`, `--sort`)
|
|
525
569
|
2. the environment (`LINEAR_TEAM`/`LINEAR_TEAM_ID`, `LINEAR_WORKSPACE`, `LINEAR_ISSUE_SORT`)
|
|
526
570
|
3. the **project config**: the first file found walking up from the working directory, checking in
|
|
527
|
-
each directory `linear.toml`, then `.linear.toml`, then `.config/linear.toml
|
|
528
|
-
|
|
529
|
-
up with its `linear config` (which writes `<git root>/.config/linear.toml`) is picked up as-is
|
|
571
|
+
each directory `linear.toml`, then `.linear.toml`, then `.config/linear.toml`; compatible
|
|
572
|
+
existing project configuration is picked up as-is
|
|
530
573
|
4. the **user config**, `~/.config/linear/config.toml` (`$XDG_CONFIG_HOME` honored)
|
|
531
|
-
5.
|
|
532
|
-
|
|
574
|
+
5. the legacy **global config**, `~/.config/linear/linear.toml` — read for non-secret settings
|
|
575
|
+
only, so a migrating user's defaults carry over
|
|
533
576
|
|
|
534
577
|
Keys: `team` (or `team_id`), `workspace`, and `sort` (or `issue_sort`). You can write these from
|
|
535
578
|
the CLI — comments and layout in an existing file are preserved, and the write is atomic:
|
|
@@ -586,8 +629,8 @@ Use `linear schema` to discover types and fields first, then reach for `linear a
|
|
|
586
629
|
### Coverage
|
|
587
630
|
|
|
588
631
|
Coverage of the SDK is **measured, not asserted.** `linear api` reaches the full GraphQL API, and
|
|
589
|
-
a generated audit ([COVERAGE.md](./COVERAGE.md)) classifies every
|
|
590
|
-
|
|
632
|
+
a generated audit ([COVERAGE.md](./COVERAGE.md)) classifies every current `LinearClient` member as
|
|
633
|
+
`curated` (a first-class command), `raw-only` (reachable via `linear api`), or
|
|
591
634
|
`excluded` (admin/integration/SDK plumbing). CI fails on any drift from the committed snapshot, so
|
|
592
635
|
the claim stays honest as the SDK evolves.
|
|
593
636
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linear-sdk-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Ergonomic command-line interface for Linear, built on @linear/sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@inquirer/prompts": "^8.7.0",
|
|
73
|
-
"@linear/sdk": "^
|
|
73
|
+
"@linear/sdk": "^92.0.0",
|
|
74
74
|
"commander": "^15.0.0",
|
|
75
75
|
"graphql": "^17.0.2",
|
|
76
76
|
"picocolors": "^1.1.1",
|
|
@@ -317,6 +317,14 @@ linear config init
|
|
|
317
317
|
linear config set
|
|
318
318
|
linear config show
|
|
319
319
|
|
|
320
|
+
linear custom-view
|
|
321
|
+
linear custom-view create
|
|
322
|
+
linear custom-view delete
|
|
323
|
+
linear custom-view list
|
|
324
|
+
linear custom-view results
|
|
325
|
+
linear custom-view update
|
|
326
|
+
linear custom-view view
|
|
327
|
+
|
|
320
328
|
linear cycle
|
|
321
329
|
linear cycle create
|
|
322
330
|
linear cycle current
|
|
@@ -481,6 +489,7 @@ prints the same). These are supplementary — `--help` on any command is authori
|
|
|
481
489
|
- [comment](references/comment.md) — Manage comments
|
|
482
490
|
- [completion](references/completion.md) — Output a shell completion script
|
|
483
491
|
- [config](references/config.md) — Show the resolved configuration (secrets redacted)
|
|
492
|
+
- [custom-view](references/custom-view.md) — Create and manage saved custom views
|
|
484
493
|
- [cycle](references/cycle.md) — Work with cycles
|
|
485
494
|
- [document](references/document.md) — Work with documents
|
|
486
495
|
- [favorite](references/favorite.md) — Manage your favorites
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# linear custom-view
|
|
2
|
+
|
|
3
|
+
> Create and manage saved custom views
|
|
4
|
+
|
|
5
|
+
Group alias: `cv`
|
|
6
|
+
|
|
7
|
+
_Generated from `linear commands --json`. `linear custom-view --help` (or `<subcommand> --help`) is authoritative._
|
|
8
|
+
|
|
9
|
+
Every command also accepts the global flags `-j/--json`, `--no-input`, `-y/--yes`, `-q/--quiet`, `--workspace <slug>`, `--api-key <key>`, `--access-token <token>`, `-t/--team <key>`, `-n/--limit <n>`, `--all`, `-f/--fields <a,b,c>`, `--no-ansi` (alias `--no-color`), and `--debug`. Only command-specific options are listed below.
|
|
10
|
+
|
|
11
|
+
### `linear custom-view`
|
|
12
|
+
|
|
13
|
+
Create and manage saved custom views
|
|
14
|
+
|
|
15
|
+
Aliases: `cv`
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
linear custom-view [options]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Output (`--json`)**: a bare object — runs `custom-view view` by default
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
id: string
|
|
25
|
+
name: string
|
|
26
|
+
type: string
|
|
27
|
+
shared: boolean
|
|
28
|
+
owner: {id: string, displayName: string} | null
|
|
29
|
+
team: {id: string, key: string, name: string} | null
|
|
30
|
+
slugId: string
|
|
31
|
+
updatedAt: string
|
|
32
|
+
description: string | null
|
|
33
|
+
filter: object
|
|
34
|
+
color: string | null
|
|
35
|
+
icon: string | null
|
|
36
|
+
creator: {id: string, displayName: string} | null
|
|
37
|
+
createdAt: string
|
|
38
|
+
archivedAt: string | null
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### `linear custom-view create`
|
|
42
|
+
|
|
43
|
+
Create an issue, project, or initiative custom view
|
|
44
|
+
|
|
45
|
+
Aliases: `new`
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
linear custom-view create [options]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Option | Description |
|
|
52
|
+
| ------------------------------- | ---------------------------------------------- |
|
|
53
|
+
| `--name <name>` | view name |
|
|
54
|
+
| `--type <type>` | entity type |
|
|
55
|
+
| `--owner <who>` | owner (me\|email\|name\|id) |
|
|
56
|
+
| `--color <hex>` | icon color |
|
|
57
|
+
| `--icon <icon>` | emoji or decorative icon identifier |
|
|
58
|
+
| `--scope-team <key\|name\|id>` | attach the view to a team |
|
|
59
|
+
| `--scope-project <id\|name>` | attach the view to a project |
|
|
60
|
+
| `--scope-initiative <id\|name>` | attach the view to an initiative |
|
|
61
|
+
| `-d, --description <text>` | view description |
|
|
62
|
+
| `--description-file <path>` | read description from a file ('-' = stdin) |
|
|
63
|
+
| `--filter <json>` | typed Linear filter as a JSON object |
|
|
64
|
+
| `--filter-file <path>` | read the filter JSON from a file ('-' = stdin) |
|
|
65
|
+
| `--shared` | share the view with the workspace |
|
|
66
|
+
| `--personal` | make the view owner-only |
|
|
67
|
+
|
|
68
|
+
**Output (`--json`)**: a receipt object
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
id: string
|
|
72
|
+
name: string
|
|
73
|
+
type: string
|
|
74
|
+
shared: boolean
|
|
75
|
+
slugId: string
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `linear custom-view delete`
|
|
79
|
+
|
|
80
|
+
Delete a custom view by UUID
|
|
81
|
+
|
|
82
|
+
Aliases: `rm`
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
linear custom-view delete [options] <id>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Output (`--json`)**: a receipt object
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
id: string
|
|
92
|
+
name: string
|
|
93
|
+
deleted: boolean
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### `linear custom-view list`
|
|
97
|
+
|
|
98
|
+
List accessible workspace and team custom views
|
|
99
|
+
|
|
100
|
+
Aliases: `ls`
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
linear custom-view list [options]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Output (`--json`)**: a bare array of objects
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
id: string
|
|
110
|
+
name: string
|
|
111
|
+
type: string
|
|
112
|
+
shared: boolean
|
|
113
|
+
owner: {id: string, displayName: string} | null
|
|
114
|
+
team: {id: string, key: string, name: string} | null
|
|
115
|
+
slugId: string
|
|
116
|
+
updatedAt: string
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `linear custom-view results`
|
|
120
|
+
|
|
121
|
+
List issues, projects, or initiatives matched by a view UUID
|
|
122
|
+
|
|
123
|
+
Aliases: `items`
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
linear custom-view results [options] <id>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Output (`--json`)**: a bare array of objects
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
type: string
|
|
133
|
+
id: string
|
|
134
|
+
identifier: string | null
|
|
135
|
+
name: string
|
|
136
|
+
url: string
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `linear custom-view update`
|
|
140
|
+
|
|
141
|
+
Update mutable fields on a custom view UUID
|
|
142
|
+
|
|
143
|
+
Aliases: `edit`
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
linear custom-view update [options] <id>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Option | Description |
|
|
150
|
+
| ------------------------------ | ---------------------------------------------- |
|
|
151
|
+
| `--name <name>` | new name |
|
|
152
|
+
| `--owner <who>` | new owner (me\|email\|name\|id) |
|
|
153
|
+
| `--color <hex>` | new icon color |
|
|
154
|
+
| `--clear-color` | clear the icon color |
|
|
155
|
+
| `--icon <icon>` | new icon |
|
|
156
|
+
| `--clear-icon` | clear the icon |
|
|
157
|
+
| `--clear-description` | clear the description |
|
|
158
|
+
| `--scope-team <key\|name\|id>` | set the public team scope |
|
|
159
|
+
| `--clear-team-scope` | clear the public team scope |
|
|
160
|
+
| `-d, --description <text>` | new description |
|
|
161
|
+
| `--description-file <path>` | read description from a file ('-' = stdin) |
|
|
162
|
+
| `--filter <json>` | typed Linear filter as a JSON object |
|
|
163
|
+
| `--filter-file <path>` | read the filter JSON from a file ('-' = stdin) |
|
|
164
|
+
| `--shared` | share the view with the workspace |
|
|
165
|
+
| `--personal` | make the view owner-only |
|
|
166
|
+
|
|
167
|
+
**Output (`--json`)**: a receipt object
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
id: string
|
|
171
|
+
name: string
|
|
172
|
+
type: string
|
|
173
|
+
shared: boolean
|
|
174
|
+
slugId: string
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### `linear custom-view view`
|
|
178
|
+
|
|
179
|
+
Show a custom view by UUID
|
|
180
|
+
|
|
181
|
+
Aliases: `show`
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
linear custom-view view [options] <id>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Output (`--json`)**: a bare object
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
id: string
|
|
191
|
+
name: string
|
|
192
|
+
type: string
|
|
193
|
+
shared: boolean
|
|
194
|
+
owner: {id: string, displayName: string} | null
|
|
195
|
+
team: {id: string, key: string, name: string} | null
|
|
196
|
+
slugId: string
|
|
197
|
+
updatedAt: string
|
|
198
|
+
description: string | null
|
|
199
|
+
filter: object
|
|
200
|
+
color: string | null
|
|
201
|
+
icon: string | null
|
|
202
|
+
creator: {id: string, displayName: string} | null
|
|
203
|
+
createdAt: string
|
|
204
|
+
archivedAt: string | null
|
|
205
|
+
```
|
package/src/cli.ts
CHANGED
|
@@ -29,6 +29,7 @@ import { registerRoadmap } from "./commands/roadmap.js";
|
|
|
29
29
|
import { registerNotification } from "./commands/notification.js";
|
|
30
30
|
import { registerOrganization } from "./commands/organization.js";
|
|
31
31
|
import { registerWebhook } from "./commands/webhook.js";
|
|
32
|
+
import { registerCustomView } from "./commands/custom-view.js";
|
|
32
33
|
import { registerOpen } from "./commands/open.js";
|
|
33
34
|
import { registerCommands, registerSchema } from "./commands/discover.js";
|
|
34
35
|
import { Context, type GlobalOptions } from "./context.js";
|
|
@@ -87,6 +88,7 @@ export function createProgram(): Command {
|
|
|
87
88
|
registerNotification(program);
|
|
88
89
|
registerOrganization(program);
|
|
89
90
|
registerWebhook(program);
|
|
91
|
+
registerCustomView(program);
|
|
90
92
|
|
|
91
93
|
// Discovery commands need the fully-built program tree, so register them last.
|
|
92
94
|
registerCommands(program);
|