linear-sdk-cli 0.8.1 → 0.8.3
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 +29 -15
- package/COVERAGE.md +4 -3
- package/MIGRATING.md +1 -1
- package/README.md +7 -7
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ 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.8.3](https://github.com/zhendalf/linear-sdk-cli/compare/v0.8.2...v0.8.3) (2026-10-19)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **deps:** finish SDK and formatter upgrades ([b511b91](https://github.com/zhendalf/linear-sdk-cli/commit/b511b91d37fee6c85e362ff1eb436985176fc5cc))
|
|
12
|
+
- **deps:** update compatible dependency versions ([0f89628](https://github.com/zhendalf/linear-sdk-cli/commit/0f89628c9f2dd4aa63f02a7b4139822e8cea3540))
|
|
13
|
+
|
|
14
|
+
## [0.8.2](https://github.com/zhendalf/linear-sdk-cli/compare/v0.8.1...v0.8.2) (2026-10-13)
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
- **deps:** update compatible dependency versions ([#90](https://github.com/zhendalf/linear-sdk-cli/issues/90)) ([e2b93d6](https://github.com/zhendalf/linear-sdk-cli/commit/e2b93d63d0cda7050367a814a96ae52023ce5648))
|
|
19
|
+
- **deps:** update inquirer prompts and oxlint ([7e3f10a](https://github.com/zhendalf/linear-sdk-cli/commit/7e3f10a07b718cbae4dafa37168d75a2008bf116))
|
|
20
|
+
|
|
7
21
|
## [0.8.1](https://github.com/zhendalf/linear-sdk-cli/compare/v0.8.0...v0.8.1) (2026-10-04)
|
|
8
22
|
|
|
9
23
|
### Bug Fixes
|
|
@@ -180,7 +194,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
180
194
|
`completion`), `fields` (key → `"string"`, `"number|null"`, `["string"]`, nested `{…}`,
|
|
181
195
|
`{nullable: {…}}` for a relation that may be null, `"comments?"` for a key present only
|
|
182
196
|
sometimes) and `variants` (the whole shape under `--web`, `--start`, `op=list`, …). New `linear
|
|
183
|
-
commands <path...>` describes one command — a bare object under `--json` (`.output.fields`),
|
|
197
|
+
commands <path...>` describes one command — a bare object under `--json` (`.output.fields`),
|
|
184
198
|
or usage, options and one `key: type` line per field for a human, plus its subcommands for a
|
|
185
199
|
group; an unknown path is `not_found` (exit 3) with the nearest paths. The shapes are declared
|
|
186
200
|
beside the interfaces they describe (`shape<IssueRow>({…})`, `src/lib/shape.ts`), where a field
|
|
@@ -225,9 +239,9 @@ commands <path...>` describes one command — a bare object under `--json` (`.ou
|
|
|
225
239
|
TES-642).** `initiative add-project <initiative> <project>` (`--sort-order`) and
|
|
226
240
|
`remove-project` (confirmed; finds the link on the project's side, so no workspace-wide paging)
|
|
227
241
|
and `initiative unarchive <id>` (resolves among archived initiatives, refuses a live one). `initiative
|
|
228
|
-
list` gains `--status`, `--owner`, `--archived` — the list stays every-status by default, and
|
|
242
|
+
list` gains `--status`, `--owner`, `--archived` — the list stays every-status by default, and
|
|
229
243
|
the reference CLI's `--all-statuses` is accepted as the no-op it is here. `initiative
|
|
230
|
-
create/update` take `--icon`/`--color`, and `initiative view` shows `icon`, `archivedAt` and
|
|
244
|
+
create/update` take `--icon`/`--color`, and `initiative view` shows `icon`, `archivedAt` and
|
|
231
245
|
the linked `projects` (`{id, name, status}`).
|
|
232
246
|
- **`project list --all-teams`, `team create --private`, health-only status updates (TES-642).**
|
|
233
247
|
`project list` is scoped to the default team and the only way out was the accidental
|
|
@@ -432,7 +446,7 @@ create/update` take `--icon`/`--color`, and `initiative view` shows `icon`, `arc
|
|
|
432
446
|
fills. **The team's default template is now applied**, as Linear's own new-issue form and the
|
|
433
447
|
reference CLI do: the API applies it _only when asked_ (verified live — a plain `issueCreate` on
|
|
434
448
|
a team with a default template returns an issue with no description), so `useDefaultTemplate:
|
|
435
|
-
true` is sent unless `--no-default-template` (also accepted under the reference's spelling,
|
|
449
|
+
true` is sent unless `--no-default-template` (also accepted under the reference's spelling,
|
|
436
450
|
`--no-use-default-template`); an explicit `--template` replaces it rather than stacking. A
|
|
437
451
|
`--parent` child now **joins its parent's project** unless `--project` says otherwise — the
|
|
438
452
|
sub-issues we created landed outside the project their parent was in — and `--milestone` can
|
|
@@ -448,7 +462,7 @@ true` is sent unless `--no-default-template` (also accepted under the reference'
|
|
|
448
462
|
TES-596). All twelve globals are registered on every command so they can sit anywhere on the
|
|
449
463
|
line, but `--fields` projects a _rendered_ result (a table or a detail block) and `--limit`/`--all`
|
|
450
464
|
cap or exhaust a _paged_ query; on the ~90 commands that print a receipt (every mutation, `issue
|
|
451
|
-
id`, `commands`, …) all three used to vanish without a word. That silence cost data: schpet's `-f`
|
|
465
|
+
id`, `commands`, …) all three used to vanish without a word. That silence cost data: schpet's `-f`
|
|
452
466
|
is `--description-file` on `project create`, so `linear project create --name X -f desc.md`
|
|
453
467
|
parsed `-f` as _our_ `--fields`, created the project with **no description**, and exited 0. Now a
|
|
454
468
|
root `preAction` hook (`assertGlobalsApply` in `lib/options.ts`, driven by two applicability
|
|
@@ -485,7 +499,7 @@ id`, `commands`, …) all three used to vanish without a word. That silence cost
|
|
|
485
499
|
the PR `ID Title` and stops copying the issue description into GitHub** (TES-637 (5)).
|
|
486
500
|
`describe` used to print `Title`, a blank line, `Fixes ID`; it now prints `ID Title`, a blank
|
|
487
501
|
line, `Linear-issue: Fixes ID`, `Linear-issue-url: <url>` — git trailers that `git
|
|
488
|
-
interpret-trailers` / `git log --format=%(trailers:key=Linear-issue)` and jj's `trailers`
|
|
502
|
+
interpret-trailers` / `git log --format=%(trailers:key=Linear-issue)` and jj's `trailers`
|
|
489
503
|
template read back, while Linear still sees the magic word directly before the id
|
|
490
504
|
(linear.app/docs/github lists `fixes` and `references` among the recognized words) and links
|
|
491
505
|
and closes the issue. `-r/--references` swaps the word. `--json` gains `url` and `message` (the
|
|
@@ -495,7 +509,7 @@ interpret-trailers` / `git log --format=%(trailers:key=Linear-issue)` and jj's `
|
|
|
495
509
|
renamed. The issue _description_ is no longer pasted into the PR body: a GitHub PR is a wider
|
|
496
510
|
audience than a Linear issue, and Linear links from the trailer, not the prose.
|
|
497
511
|
- **A team-scoped listing with no team says it is listing every team's** (TES-637 (8)). `issue
|
|
498
|
-
list`/`mine`/`search` and `project list` with no `--team`, no configured team and no
|
|
512
|
+
list`/`mine`/`search` and `project list` with no `--team`, no configured team and no
|
|
499
513
|
`--all-teams` list the whole workspace — by design; schpet errors there ("No default team…"), so
|
|
500
514
|
someone arriving from it could read the workspace as the team. One `info` line on stderr ("No
|
|
501
515
|
default team configured; listing every team's. Pass --team <KEY> …"), silenced by `--quiet`,
|
|
@@ -598,7 +612,7 @@ list`/`mine`/`search` and `project list` with no `--team`, no configured team an
|
|
|
598
612
|
|
|
599
613
|
- **`issue list`/`mine`/`search` rows omitted `milestone` and `cycle`** (TES-652). The list
|
|
600
614
|
query selected project and labels but neither relation, so `issue list --project X --json | jq
|
|
601
|
-
'group_by(.milestone.name)'` put every issue in the null bucket while `issue view` showed the
|
|
615
|
+
'group_by(.milestone.name)'` put every issue in the null bucket while `issue view` showed the
|
|
602
616
|
milestone. Rows now carry `milestone: {id, name} | null` and `cycle: {id, number, name} | null`
|
|
603
617
|
— the detail's exact object shapes, from the one existing query (two selections, no extra
|
|
604
618
|
request; `LIST_QUERY` and `SEARCH_QUERY` share the relation block so they cannot drift again).
|
|
@@ -619,7 +633,7 @@ list`/`mine`/`search` and `project list` with no `--team`, no configured team an
|
|
|
619
633
|
Non-interactively, `comment update <id>` with no body is a usage error, not an editor.
|
|
620
634
|
- **`issue comment "<body>"` on a matching branch failed** (TES-619) — the README's headline
|
|
621
635
|
example. `issue comment [id] [body]` read a lone operand as the id, so `linear issue comment
|
|
622
|
-
'shipped'` on `tes-615-…` produced "No comment body provided" (and, in a terminal, opened
|
|
636
|
+
'shipped'` on `tes-615-…` produced "No comment body provided" (and, in a terminal, opened
|
|
623
637
|
`$EDITOR` for the body first and only then rejected `'shipped'` as an id — work lost).
|
|
624
638
|
`assign` and `state` already disambiguated a lone operand; `comment` now does the same: one
|
|
625
639
|
operand that looks like an issue id is the id (body from `--body-file` or the editor), anything
|
|
@@ -649,7 +663,7 @@ list`/`mine`/`search` and `project list` with no `--team`, no configured team an
|
|
|
649
663
|
`--help`; a bare group shows its help** (TES-633). The root has an action (bare `linear` shows the
|
|
650
664
|
branch's issue) and `issue` has a default subcommand (`view`), so commander's own "unknown
|
|
651
665
|
command" never fired for either: `linear issues list` was `too many arguments. Expected 0
|
|
652
|
-
arguments but got 2: issues, list.` and `linear issue lst` was `'lst' is not a valid issue id`.
|
|
666
|
+
arguments but got 2: issues, list.` and `linear issue lst` was `'lst' is not a valid issue id`.
|
|
653
667
|
Now: `Unknown command 'issues'. Did you mean 'issue'? Run 'linear --help' to see the commands.`
|
|
654
668
|
and `'lst' is not a valid issue id (…). Did you mean 'linear issue list'?` — a prefix (`proj`),
|
|
655
669
|
a small typo (`lable`, `isue`) or an alias (`docs`, `notif`) is close enough; two-letter aliases
|
|
@@ -684,7 +698,7 @@ arguments but got 2: issues, list.` and `linear issue lst` was `'lst' is not a v
|
|
|
684
698
|
resolves the name inside that project (names are unique per project only, the same rule
|
|
685
699
|
`issue update --milestone` applies); a name without `--project` is a usage error that says so:
|
|
686
700
|
`'…' is not a milestone id; pass --project <name|id> to look a milestone up by name.` `state view
|
|
687
|
-
<name-or-type>` resolves against `--team` or the configured default team, exactly as
|
|
701
|
+
<name-or-type>` resolves against `--team` or the configured default team, exactly as
|
|
688
702
|
`issue create --state` does, and says to pass `--team` when there is neither. UUIDs still go
|
|
689
703
|
straight through.
|
|
690
704
|
- **`milestone list`/`view` printed progress ×100 — `3846%`** (TES-648, found while fixing the
|
|
@@ -807,7 +821,7 @@ arguments but got 2: issues, list.` and `linear issue lst` was `'lst' is not a v
|
|
|
807
821
|
issue id inferred from the current branch as usual. `issue describe [id]` prints the issue
|
|
808
822
|
title plus a commit-message trailer using Linear's git magic words (`Fixes <ID>`, or
|
|
809
823
|
`References <ID>` with `-r`/`--references`) — drop it into `git commit -m "$(linear issue
|
|
810
|
-
describe)"`. `issue pull-request [id]` (alias `pr`) creates a GitHub PR via the `gh` CLI:
|
|
824
|
+
describe)"`. `issue pull-request [id]` (alias `pr`) creates a GitHub PR via the `gh` CLI:
|
|
811
825
|
the title defaults to the issue title (`--title` to override) and the body is the issue
|
|
812
826
|
description followed by a `Fixes <ID>` trailer and the Linear URL, so the PR and issue
|
|
813
827
|
reference each other. Flags: `--base`, `--head`, `--draft`, `--web`. The created PR URL is the
|
|
@@ -816,8 +830,8 @@ describe)"`. `issue pull-request [id]` (alias `pr`) creates a GitHub PR via the
|
|
|
816
830
|
or when `gh` itself fails.
|
|
817
831
|
- **Multi-workspace credentials.** Store API keys for several workspaces and switch between
|
|
818
832
|
them. New `auth` subcommands: `auth list` (configured workspaces + default), `auth default
|
|
819
|
-
<slug>` (set the default), and `auth token` (print the resolved key for scripting). `auth
|
|
820
|
-
login` now accepts the global `--workspace <slug>` (derived from the key's organization when
|
|
833
|
+
<slug>` (set the default), and `auth token` (print the resolved key for scripting). `auth
|
|
834
|
+
login` now accepts the global `--workspace <slug>` (derived from the key's organization when
|
|
821
835
|
omitted) and `auth status` reports the active credential workspace. A new global
|
|
822
836
|
`--workspace <slug>` selects which stored credential to use for any command. Credentials live
|
|
823
837
|
in quoted `[workspaces."<slug>"]` tables under a top-level `default_workspace`. Credential
|
|
@@ -921,7 +935,7 @@ login` now accepts the global `--workspace <slug>` (derived from the key's organ
|
|
|
921
935
|
stderr, where it lands in scrollback, CI logs and bug reports. The same channel let a project
|
|
922
936
|
`.linear.toml` — a file that is not ours and may arrive with a checkout — emit raw escape
|
|
923
937
|
sequences through our error output. We now report only the reason and the position (`line 3,
|
|
924
|
-
column 36`), never an excerpt from a credential-bearing file, and strip control characters and
|
|
938
|
+
column 36`), never an excerpt from a credential-bearing file, and strip control characters and
|
|
925
939
|
bidi overrides from what remains. The error stays actionable: it still says exactly where to look.
|
|
926
940
|
- **Credential writes could lose a config or leave a truncated one.** Writing the config in place
|
|
927
941
|
truncates it first, so a crash or a concurrently-running `linear` could observe — or leave behind
|
package/COVERAGE.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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: **481**.
|
|
4
4
|
|
|
5
5
|
| Status | Count | Meaning |
|
|
6
6
|
| -------- | ----- | ----------------------------------------------- |
|
|
7
7
|
| curated | 107 | Has a first-class CLI command |
|
|
8
|
-
| raw-only |
|
|
8
|
+
| raw-only | 146 | Reachable via `linear api` (no bespoke command) |
|
|
9
9
|
| excluded | 228 | Out of scope (admin/integration/SDK plumbing) |
|
|
10
10
|
|
|
11
11
|
Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
@@ -356,7 +356,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
356
356
|
- `userUnlinkFromIdentityProvider` — admin/enterprise (raw api only)
|
|
357
357
|
- `userViewPreferences` — specialized/raw api only
|
|
358
358
|
|
|
359
|
-
## Raw-only (
|
|
359
|
+
## Raw-only (146)
|
|
360
360
|
|
|
361
361
|
<details><summary>Show</summary>
|
|
362
362
|
|
|
@@ -458,6 +458,7 @@ Every member is classified — CI fails otherwise. `raw-only` members are still
|
|
|
458
458
|
- `projectRemoveLabel`
|
|
459
459
|
- `projectStatus`
|
|
460
460
|
- `projectUpdate`
|
|
461
|
+
- `quotas`
|
|
461
462
|
- `refreshGoogleSheetsData`
|
|
462
463
|
- `resendOrganizationInvite`
|
|
463
464
|
- `resendOrganizationInviteByEmail`
|
package/MIGRATING.md
CHANGED
|
@@ -179,7 +179,7 @@ Every one is now either identical, or says so on stderr, or is a usage error. Kn
|
|
|
179
179
|
8. **`issue describe`** — theirs prints `ID Title`, a blank line, then `Linear-issue: Fixes ID` and
|
|
180
180
|
`Linear-issue-url: URL`; ours printed `Title` and a bare `Fixes ID`. Piped into `git commit -m`
|
|
181
181
|
that was a different commit. Adopted, byte for byte: proper trailers are what `git
|
|
182
|
-
interpret-trailers` and jj read back, and Linear reads the magic word right before the id
|
|
182
|
+
interpret-trailers` and jj read back, and Linear reads the magic word right before the id
|
|
183
183
|
either way (linear.app/docs/github). `-r/--references` still swaps in `References`.
|
|
184
184
|
9. **`issue pull-request`** — theirs titles the PR `ID Title` and sends the issue URL as the body;
|
|
185
185
|
ours titled it `Title` and pasted the issue _description_ into the body. Title adopted (a custom
|
package/README.md
CHANGED
|
@@ -795,15 +795,15 @@ profile metadata. Logout reports whether removing a whole profile also removed i
|
|
|
795
795
|
|
|
796
796
|
```toml
|
|
797
797
|
# ~/.config/linear/config.toml
|
|
798
|
-
default_workspace = "acme"
|
|
799
|
-
team = "TES"
|
|
800
|
-
sort = "priority"
|
|
798
|
+
default_workspace = "acme" # which stored credential is active
|
|
799
|
+
team = "TES" # optional legacy/global fallback team
|
|
800
|
+
sort = "priority" # default issue-list sort: priority | updated | created
|
|
801
801
|
|
|
802
|
-
[workspaces."acme"]
|
|
803
|
-
keyring = true
|
|
804
|
-
team = "ENG"
|
|
802
|
+
[workspaces."acme"] # per-workspace credentials (hyphenated slugs are quoted)
|
|
803
|
+
keyring = true # secret lives in the OS keyring (service linear-cli, account acme)
|
|
804
|
+
team = "ENG" # non-secret default team for this workspace
|
|
805
805
|
[workspaces."other-org"]
|
|
806
|
-
api_key = "lin_api_yyyyyyyy"
|
|
806
|
+
api_key = "lin_api_yyyyyyyy" # …or, with `auth login --plaintext`, in this 0600 file
|
|
807
807
|
team = "OPS"
|
|
808
808
|
```
|
|
809
809
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linear-sdk-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Ergonomic command-line interface for Linear, built on @linear/sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"lin": "bun run src/bin/linear.ts",
|
|
55
55
|
"typecheck": "tsc --noEmit",
|
|
56
56
|
"lint": "oxlint .",
|
|
57
|
-
"format": "oxfmt .",
|
|
58
|
-
"format:check": "oxfmt --check .",
|
|
57
|
+
"format": "oxfmt . '!CHANGELOG.md'",
|
|
58
|
+
"format:check": "oxfmt --check . '!CHANGELOG.md'",
|
|
59
59
|
"test": "bun test test/unit test/contract",
|
|
60
60
|
"test:performance": "bun test --timeout 15000 test/performance",
|
|
61
61
|
"test:unit": "bun test test/unit",
|
|
@@ -70,19 +70,19 @@
|
|
|
70
70
|
"janitor": "bun run test/janitor.ts"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@inquirer/prompts": "^8.7.
|
|
74
|
-
"@linear/sdk": "^
|
|
73
|
+
"@inquirer/prompts": "^8.7.3",
|
|
74
|
+
"@linear/sdk": "^98.0.0",
|
|
75
75
|
"commander": "^15.0.0",
|
|
76
76
|
"graphql": "^17.0.2",
|
|
77
77
|
"picocolors": "^1.1.1",
|
|
78
|
-
"smol-toml": "^1.9.
|
|
78
|
+
"smol-toml": "^1.9.1"
|
|
79
79
|
},
|
|
80
|
-
"packageManager": "bun@1.4.
|
|
80
|
+
"packageManager": "bun@1.4.3",
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@types/bun": "^1.4.
|
|
83
|
-
"@types/node": "^26.6.
|
|
84
|
-
"oxfmt": "^0.
|
|
85
|
-
"oxlint": "^1.
|
|
82
|
+
"@types/bun": "^1.4.3",
|
|
83
|
+
"@types/node": "^26.6.5",
|
|
84
|
+
"oxfmt": "^0.73.0",
|
|
85
|
+
"oxlint": "^1.88.0",
|
|
86
86
|
"typescript": "^7.0.2"
|
|
87
87
|
}
|
|
88
88
|
}
|