linear-sdk-cli 0.8.2 → 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 +22 -15
- package/MIGRATING.md +1 -1
- package/README.md +7 -7
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ 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
|
+
|
|
7
14
|
## [0.8.2](https://github.com/zhendalf/linear-sdk-cli/compare/v0.8.1...v0.8.2) (2026-10-13)
|
|
8
15
|
|
|
9
16
|
### Bug Fixes
|
|
@@ -187,7 +194,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
187
194
|
`completion`), `fields` (key → `"string"`, `"number|null"`, `["string"]`, nested `{…}`,
|
|
188
195
|
`{nullable: {…}}` for a relation that may be null, `"comments?"` for a key present only
|
|
189
196
|
sometimes) and `variants` (the whole shape under `--web`, `--start`, `op=list`, …). New `linear
|
|
190
|
-
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`),
|
|
191
198
|
or usage, options and one `key: type` line per field for a human, plus its subcommands for a
|
|
192
199
|
group; an unknown path is `not_found` (exit 3) with the nearest paths. The shapes are declared
|
|
193
200
|
beside the interfaces they describe (`shape<IssueRow>({…})`, `src/lib/shape.ts`), where a field
|
|
@@ -232,9 +239,9 @@ commands <path...>` describes one command — a bare object under `--json` (`.ou
|
|
|
232
239
|
TES-642).** `initiative add-project <initiative> <project>` (`--sort-order`) and
|
|
233
240
|
`remove-project` (confirmed; finds the link on the project's side, so no workspace-wide paging)
|
|
234
241
|
and `initiative unarchive <id>` (resolves among archived initiatives, refuses a live one). `initiative
|
|
235
|
-
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
|
|
236
243
|
the reference CLI's `--all-statuses` is accepted as the no-op it is here. `initiative
|
|
237
|
-
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
|
|
238
245
|
the linked `projects` (`{id, name, status}`).
|
|
239
246
|
- **`project list --all-teams`, `team create --private`, health-only status updates (TES-642).**
|
|
240
247
|
`project list` is scoped to the default team and the only way out was the accidental
|
|
@@ -439,7 +446,7 @@ create/update` take `--icon`/`--color`, and `initiative view` shows `icon`, `arc
|
|
|
439
446
|
fills. **The team's default template is now applied**, as Linear's own new-issue form and the
|
|
440
447
|
reference CLI do: the API applies it _only when asked_ (verified live — a plain `issueCreate` on
|
|
441
448
|
a team with a default template returns an issue with no description), so `useDefaultTemplate:
|
|
442
|
-
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,
|
|
443
450
|
`--no-use-default-template`); an explicit `--template` replaces it rather than stacking. A
|
|
444
451
|
`--parent` child now **joins its parent's project** unless `--project` says otherwise — the
|
|
445
452
|
sub-issues we created landed outside the project their parent was in — and `--milestone` can
|
|
@@ -455,7 +462,7 @@ true` is sent unless `--no-default-template` (also accepted under the reference'
|
|
|
455
462
|
TES-596). All twelve globals are registered on every command so they can sit anywhere on the
|
|
456
463
|
line, but `--fields` projects a _rendered_ result (a table or a detail block) and `--limit`/`--all`
|
|
457
464
|
cap or exhaust a _paged_ query; on the ~90 commands that print a receipt (every mutation, `issue
|
|
458
|
-
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`
|
|
459
466
|
is `--description-file` on `project create`, so `linear project create --name X -f desc.md`
|
|
460
467
|
parsed `-f` as _our_ `--fields`, created the project with **no description**, and exited 0. Now a
|
|
461
468
|
root `preAction` hook (`assertGlobalsApply` in `lib/options.ts`, driven by two applicability
|
|
@@ -492,7 +499,7 @@ id`, `commands`, …) all three used to vanish without a word. That silence cost
|
|
|
492
499
|
the PR `ID Title` and stops copying the issue description into GitHub** (TES-637 (5)).
|
|
493
500
|
`describe` used to print `Title`, a blank line, `Fixes ID`; it now prints `ID Title`, a blank
|
|
494
501
|
line, `Linear-issue: Fixes ID`, `Linear-issue-url: <url>` — git trailers that `git
|
|
495
|
-
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`
|
|
496
503
|
template read back, while Linear still sees the magic word directly before the id
|
|
497
504
|
(linear.app/docs/github lists `fixes` and `references` among the recognized words) and links
|
|
498
505
|
and closes the issue. `-r/--references` swaps the word. `--json` gains `url` and `message` (the
|
|
@@ -502,7 +509,7 @@ interpret-trailers` / `git log --format=%(trailers:key=Linear-issue)` and jj's `
|
|
|
502
509
|
renamed. The issue _description_ is no longer pasted into the PR body: a GitHub PR is a wider
|
|
503
510
|
audience than a Linear issue, and Linear links from the trailer, not the prose.
|
|
504
511
|
- **A team-scoped listing with no team says it is listing every team's** (TES-637 (8)). `issue
|
|
505
|
-
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
|
|
506
513
|
`--all-teams` list the whole workspace — by design; schpet errors there ("No default team…"), so
|
|
507
514
|
someone arriving from it could read the workspace as the team. One `info` line on stderr ("No
|
|
508
515
|
default team configured; listing every team's. Pass --team <KEY> …"), silenced by `--quiet`,
|
|
@@ -605,7 +612,7 @@ list`/`mine`/`search` and `project list` with no `--team`, no configured team an
|
|
|
605
612
|
|
|
606
613
|
- **`issue list`/`mine`/`search` rows omitted `milestone` and `cycle`** (TES-652). The list
|
|
607
614
|
query selected project and labels but neither relation, so `issue list --project X --json | jq
|
|
608
|
-
'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
|
|
609
616
|
milestone. Rows now carry `milestone: {id, name} | null` and `cycle: {id, number, name} | null`
|
|
610
617
|
— the detail's exact object shapes, from the one existing query (two selections, no extra
|
|
611
618
|
request; `LIST_QUERY` and `SEARCH_QUERY` share the relation block so they cannot drift again).
|
|
@@ -626,7 +633,7 @@ list`/`mine`/`search` and `project list` with no `--team`, no configured team an
|
|
|
626
633
|
Non-interactively, `comment update <id>` with no body is a usage error, not an editor.
|
|
627
634
|
- **`issue comment "<body>"` on a matching branch failed** (TES-619) — the README's headline
|
|
628
635
|
example. `issue comment [id] [body]` read a lone operand as the id, so `linear issue comment
|
|
629
|
-
'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
|
|
630
637
|
`$EDITOR` for the body first and only then rejected `'shipped'` as an id — work lost).
|
|
631
638
|
`assign` and `state` already disambiguated a lone operand; `comment` now does the same: one
|
|
632
639
|
operand that looks like an issue id is the id (body from `--body-file` or the editor), anything
|
|
@@ -656,7 +663,7 @@ list`/`mine`/`search` and `project list` with no `--team`, no configured team an
|
|
|
656
663
|
`--help`; a bare group shows its help** (TES-633). The root has an action (bare `linear` shows the
|
|
657
664
|
branch's issue) and `issue` has a default subcommand (`view`), so commander's own "unknown
|
|
658
665
|
command" never fired for either: `linear issues list` was `too many arguments. Expected 0
|
|
659
|
-
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`.
|
|
660
667
|
Now: `Unknown command 'issues'. Did you mean 'issue'? Run 'linear --help' to see the commands.`
|
|
661
668
|
and `'lst' is not a valid issue id (…). Did you mean 'linear issue list'?` — a prefix (`proj`),
|
|
662
669
|
a small typo (`lable`, `isue`) or an alias (`docs`, `notif`) is close enough; two-letter aliases
|
|
@@ -691,7 +698,7 @@ arguments but got 2: issues, list.` and `linear issue lst` was `'lst' is not a v
|
|
|
691
698
|
resolves the name inside that project (names are unique per project only, the same rule
|
|
692
699
|
`issue update --milestone` applies); a name without `--project` is a usage error that says so:
|
|
693
700
|
`'…' is not a milestone id; pass --project <name|id> to look a milestone up by name.` `state view
|
|
694
|
-
<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
|
|
695
702
|
`issue create --state` does, and says to pass `--team` when there is neither. UUIDs still go
|
|
696
703
|
straight through.
|
|
697
704
|
- **`milestone list`/`view` printed progress ×100 — `3846%`** (TES-648, found while fixing the
|
|
@@ -814,7 +821,7 @@ arguments but got 2: issues, list.` and `linear issue lst` was `'lst' is not a v
|
|
|
814
821
|
issue id inferred from the current branch as usual. `issue describe [id]` prints the issue
|
|
815
822
|
title plus a commit-message trailer using Linear's git magic words (`Fixes <ID>`, or
|
|
816
823
|
`References <ID>` with `-r`/`--references`) — drop it into `git commit -m "$(linear issue
|
|
817
|
-
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:
|
|
818
825
|
the title defaults to the issue title (`--title` to override) and the body is the issue
|
|
819
826
|
description followed by a `Fixes <ID>` trailer and the Linear URL, so the PR and issue
|
|
820
827
|
reference each other. Flags: `--base`, `--head`, `--draft`, `--web`. The created PR URL is the
|
|
@@ -823,8 +830,8 @@ describe)"`. `issue pull-request [id]` (alias `pr`) creates a GitHub PR via the
|
|
|
823
830
|
or when `gh` itself fails.
|
|
824
831
|
- **Multi-workspace credentials.** Store API keys for several workspaces and switch between
|
|
825
832
|
them. New `auth` subcommands: `auth list` (configured workspaces + default), `auth default
|
|
826
|
-
<slug>` (set the default), and `auth token` (print the resolved key for scripting). `auth
|
|
827
|
-
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
|
|
828
835
|
omitted) and `auth status` reports the active credential workspace. A new global
|
|
829
836
|
`--workspace <slug>` selects which stored credential to use for any command. Credentials live
|
|
830
837
|
in quoted `[workspaces."<slug>"]` tables under a top-level `default_workspace`. Credential
|
|
@@ -928,7 +935,7 @@ login` now accepts the global `--workspace <slug>` (derived from the key's organ
|
|
|
928
935
|
stderr, where it lands in scrollback, CI logs and bug reports. The same channel let a project
|
|
929
936
|
`.linear.toml` — a file that is not ours and may arrive with a checkout — emit raw escape
|
|
930
937
|
sequences through our error output. We now report only the reason and the position (`line 3,
|
|
931
|
-
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
|
|
932
939
|
bidi overrides from what remains. The error stays actionable: it still says exactly where to look.
|
|
933
940
|
- **Credential writes could lose a config or leave a truncated one.** Writing the config in place
|
|
934
941
|
truncates it first, so a crash or a concurrently-running `linear` could observe — or leave behind
|
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",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@inquirer/prompts": "^8.7.3",
|
|
74
|
-
"@linear/sdk": "^
|
|
74
|
+
"@linear/sdk": "^98.0.0",
|
|
75
75
|
"commander": "^15.0.0",
|
|
76
76
|
"graphql": "^17.0.2",
|
|
77
77
|
"picocolors": "^1.1.1",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@types/bun": "^1.4.3",
|
|
83
83
|
"@types/node": "^26.6.5",
|
|
84
|
-
"oxfmt": "^0.
|
|
85
|
-
"oxlint": "^1.
|
|
84
|
+
"oxfmt": "^0.73.0",
|
|
85
|
+
"oxlint": "^1.88.0",
|
|
86
86
|
"typescript": "^7.0.2"
|
|
87
87
|
}
|
|
88
88
|
}
|