linear-sdk-cli 0.4.0 → 0.5.1
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 +17 -0
- package/COVERAGE.md +8 -3
- package/MIGRATING.md +6 -0
- package/README.md +193 -37
- package/package.json +8 -7
- package/skills/linear-sdk-cli/SKILL.md +11 -0
- package/skills/linear-sdk-cli/references/auth.md +4 -1
- package/skills/linear-sdk-cli/references/comment.md +2 -0
- package/skills/linear-sdk-cli/references/config.md +10 -7
- package/skills/linear-sdk-cli/references/initiative.md +10 -5
- package/skills/linear-sdk-cli/references/issue.md +224 -77
- package/skills/linear-sdk-cli/references/notification.md +3 -3
- package/skills/linear-sdk-cli/references/project.md +9 -4
- package/src/cli.ts +1 -0
- package/src/commands/comment.ts +9 -7
- package/src/commands/initiative.ts +23 -6
- package/src/commands/issue.ts +313 -12
- package/src/commands/meta.ts +85 -13
- package/src/commands/notification.ts +5 -3
- package/src/commands/open.ts +2 -1
- package/src/commands/project.ts +21 -3
- package/src/config.ts +124 -39
- package/src/context.ts +21 -1
- package/src/lib/action.ts +8 -0
- package/src/lib/delegation.ts +240 -0
- package/src/lib/options.ts +17 -3
- package/src/lib/output-shapes.ts +78 -3
- package/src/lib/resolve.ts +53 -39
- package/src/output/lifecycle.ts +10 -0
- package/src/services/initiative.ts +12 -3
- package/src/services/issue.ts +498 -21
- package/src/services/project.ts +14 -3
|
@@ -38,6 +38,7 @@ updatedAt: string
|
|
|
38
38
|
startedAt: string | null
|
|
39
39
|
completedAt: string | null
|
|
40
40
|
archivedAt: string | null
|
|
41
|
+
trashed: boolean
|
|
41
42
|
owner: string | null
|
|
42
43
|
creator: string | null
|
|
43
44
|
projects: Array<{id: string, name: string, status: {name: string, type: string} | null}>
|
|
@@ -138,11 +139,12 @@ Aliases: `ls`
|
|
|
138
139
|
linear initiative list [options]
|
|
139
140
|
```
|
|
140
141
|
|
|
141
|
-
| Option
|
|
142
|
-
|
|
|
143
|
-
| `--status <name>`
|
|
144
|
-
| `--owner <who>`
|
|
145
|
-
| `--archived`
|
|
142
|
+
| Option | Description |
|
|
143
|
+
| -------------------- | -------------------------------------------------------------------- |
|
|
144
|
+
| `--status <name>` | filter by status (Planned, Active, Completed, Canceled, Proposed) |
|
|
145
|
+
| `--owner <who>` | filter by owner (me\|email\|name\|id) |
|
|
146
|
+
| `--include-archived` | include archived resources (the API may also return trashed records) |
|
|
147
|
+
| `--archived` | compatibility alias of --include-archived |
|
|
146
148
|
|
|
147
149
|
**Output (`--json`)**: a bare array of objects
|
|
148
150
|
|
|
@@ -154,6 +156,8 @@ priority: number
|
|
|
154
156
|
targetDate: string | null
|
|
155
157
|
health: string | null
|
|
156
158
|
url: string
|
|
159
|
+
archivedAt: string | null
|
|
160
|
+
trashed: boolean
|
|
157
161
|
```
|
|
158
162
|
|
|
159
163
|
### `linear initiative remove-project`
|
|
@@ -250,6 +254,7 @@ updatedAt: string
|
|
|
250
254
|
startedAt: string | null
|
|
251
255
|
completedAt: string | null
|
|
252
256
|
archivedAt: string | null
|
|
257
|
+
trashed: boolean
|
|
253
258
|
owner: string | null
|
|
254
259
|
creator: string | null
|
|
255
260
|
projects: Array<{id: string, name: string, status: {name: string, type: string} | null}>
|
|
@@ -40,6 +40,7 @@ completedAt: string | null
|
|
|
40
40
|
canceledAt: string | null
|
|
41
41
|
state: {id: string, name: string, type: string} | null
|
|
42
42
|
assignee: {id: string, displayName: string, email: string} | null
|
|
43
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
43
44
|
team: {id: string, key: string, name: string} | null
|
|
44
45
|
project: {id: string, name: string} | null
|
|
45
46
|
milestone: {id: string, name: string} | null
|
|
@@ -254,6 +255,8 @@ issue: string
|
|
|
254
255
|
|
|
255
256
|
Add a comment to an issue (images uploaded with --attach render inline)
|
|
256
257
|
|
|
258
|
+
Aliases: `create`
|
|
259
|
+
|
|
257
260
|
```
|
|
258
261
|
linear issue comment add [options] <issue> [body]
|
|
259
262
|
```
|
|
@@ -368,6 +371,10 @@ linear issue create [options]
|
|
|
368
371
|
| `--description-file <path>` | read description from a file ('-' = stdin) |
|
|
369
372
|
| `--editor` | compose the description in $EDITOR |
|
|
370
373
|
| `-a, --assignee <who>` | assignee (me\|email\|name\|id) |
|
|
374
|
+
| `--delegate <agent>` | delegate to an eligible agent app user (name or id) |
|
|
375
|
+
| `--clear-delegate` | explicitly create with no agent delegate |
|
|
376
|
+
| `--dry-run` | resolve and show the delegation mutation input without writing |
|
|
377
|
+
| `--full-result` | read back and verify the resulting delegate |
|
|
371
378
|
| `-s, --state <name>` | workflow state name or type |
|
|
372
379
|
| `-P, --priority <0-4>` | priority |
|
|
373
380
|
| `-l, --label <name>` | label (repeatable / comma-separated) |
|
|
@@ -397,6 +404,78 @@ checkedOut: boolean
|
|
|
397
404
|
stateChanged: boolean
|
|
398
405
|
```
|
|
399
406
|
|
|
407
|
+
With `--delegate`: the same, plus:
|
|
408
|
+
|
|
409
|
+
```text
|
|
410
|
+
assignee: {id: string, displayName: string, email: string} | null
|
|
411
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
With `--clear-delegate`: the same, plus:
|
|
415
|
+
|
|
416
|
+
```text
|
|
417
|
+
assignee: {id: string, displayName: string, email: string} | null
|
|
418
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
With `--dry-run`: a receipt object
|
|
422
|
+
|
|
423
|
+
```text
|
|
424
|
+
operation: string
|
|
425
|
+
dryRun: boolean
|
|
426
|
+
target: {id: string, identifier: string} | null
|
|
427
|
+
input: object
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
With `--full-result`: a receipt object
|
|
431
|
+
|
|
432
|
+
```text
|
|
433
|
+
receipt: {id: string, identifier: string, url: string, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null}
|
|
434
|
+
resource: {id: string, identifier: string, title: string, description: string | null, priority: number, priorityLabel: string, estimate: number | null, url: string, branchName: string, dueDate: string | null, createdAt: string, updatedAt: string, archivedAt: string | null, trashed: boolean, startedAt: string | null, completedAt: string | null, canceledAt: string | null, state: {id: string, name: string, type: string} | null, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null, team: {id: string, key: string, name: string} | null, project: {id: string, name: string} | null, milestone: {id: string, name: string} | null, cycle: {id: string, number: number, name: string | null} | null, parent: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null} | null, children: Array<{id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}>, labels: Array<{id: string, name: string}>, subscribers: Array<{id: string, displayName: string}>, attachments: Array<{id: string, title: string, url: string, subtitle: string | null, sourceType: string | null, createdAt: string}>, documents: Array<{id: string, title: string, slugId: string, url: string, createdAt: string, updatedAt: string}>, relations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, inverseRelations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, comments: Array<{id: string, body: string, url: string, createdAt: string, editedAt: string | null, resolvedAt: string | null, parent: {id: string} | null, user: {id: string, displayName: string} | null, externalUser: {id: string, displayName: string} | null, resolvingCommentId: string | null, resolvingUser: {id: string, displayName: string} | null}>}
|
|
435
|
+
verified: boolean
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### `linear issue delegate`
|
|
439
|
+
|
|
440
|
+
Delegate an issue to an eligible agent, or --clear it. Issue defaults to the branch.
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
linear issue delegate [options] [idOrAgent] [agent]
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
| Option | Description |
|
|
447
|
+
| --------------- | ---------------------------------------------------------- |
|
|
448
|
+
| `--clear` | remove the agent delegate |
|
|
449
|
+
| `--dry-run` | resolve and show the exact delegateId without writing |
|
|
450
|
+
| `--full-result` | read back the full issue and verify the resulting delegate |
|
|
451
|
+
|
|
452
|
+
**Output (`--json`)**: a receipt object
|
|
453
|
+
|
|
454
|
+
```text
|
|
455
|
+
id: string
|
|
456
|
+
identifier: string
|
|
457
|
+
url: string
|
|
458
|
+
assignee: {id: string, displayName: string, email: string} | null
|
|
459
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
With `--dry-run`: a receipt object
|
|
463
|
+
|
|
464
|
+
```text
|
|
465
|
+
operation: string
|
|
466
|
+
dryRun: boolean
|
|
467
|
+
target: {id: string, identifier: string} | null
|
|
468
|
+
input: object
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
With `--full-result`: a receipt object
|
|
472
|
+
|
|
473
|
+
```text
|
|
474
|
+
receipt: {id: string, identifier: string, url: string, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null}
|
|
475
|
+
resource: {id: string, identifier: string, title: string, description: string | null, priority: number, priorityLabel: string, estimate: number | null, url: string, branchName: string, dueDate: string | null, createdAt: string, updatedAt: string, archivedAt: string | null, trashed: boolean, startedAt: string | null, completedAt: string | null, canceledAt: string | null, state: {id: string, name: string, type: string} | null, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null, team: {id: string, key: string, name: string} | null, project: {id: string, name: string} | null, milestone: {id: string, name: string} | null, cycle: {id: string, number: number, name: string | null} | null, parent: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null} | null, children: Array<{id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}>, labels: Array<{id: string, name: string}>, subscribers: Array<{id: string, displayName: string}>, attachments: Array<{id: string, title: string, url: string, subtitle: string | null, sourceType: string | null, createdAt: string}>, documents: Array<{id: string, title: string, slugId: string, url: string, createdAt: string, updatedAt: string}>, relations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, inverseRelations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, comments: Array<{id: string, body: string, url: string, createdAt: string, editedAt: string | null, resolvedAt: string | null, parent: {id: string} | null, user: {id: string, displayName: string} | null, externalUser: {id: string, displayName: string} | null, resolvingCommentId: string | null, resolvingUser: {id: string, displayName: string} | null}>}
|
|
476
|
+
verified: boolean
|
|
477
|
+
```
|
|
478
|
+
|
|
400
479
|
### `linear issue delete`
|
|
401
480
|
|
|
402
481
|
Delete (trash) an issue
|
|
@@ -468,16 +547,19 @@ id: string
|
|
|
468
547
|
|
|
469
548
|
### `linear issue label`
|
|
470
549
|
|
|
471
|
-
Add
|
|
550
|
+
Add, remove, or replace one member of a label group on an issue
|
|
472
551
|
|
|
473
552
|
```
|
|
474
553
|
linear issue label [options] [id]
|
|
475
554
|
```
|
|
476
555
|
|
|
477
|
-
| Option
|
|
478
|
-
|
|
|
479
|
-
| `--add <name>`
|
|
480
|
-
| `--remove <name>`
|
|
556
|
+
| Option | Description |
|
|
557
|
+
| --------------------------- | ------------------------------------------------------------------ |
|
|
558
|
+
| `--add <name>` | add a label (repeatable) |
|
|
559
|
+
| `--remove <name>` | remove a label (repeatable) |
|
|
560
|
+
| `--set-group <group=label>` | replace a group's direct member (repeatable; exact name or UUID) |
|
|
561
|
+
| `--dry-run` | resolve and show the exact relative-label mutation without writing |
|
|
562
|
+
| `--full-result` | read back and verify the resulting group labels |
|
|
481
563
|
|
|
482
564
|
**Output (`--json`)**: a receipt object
|
|
483
565
|
|
|
@@ -486,6 +568,35 @@ id: string
|
|
|
486
568
|
identifier: string
|
|
487
569
|
```
|
|
488
570
|
|
|
571
|
+
With `--set-group`: the same, plus:
|
|
572
|
+
|
|
573
|
+
```text
|
|
574
|
+
changed: boolean
|
|
575
|
+
mutationSent: boolean
|
|
576
|
+
groups: Array<{group: {id: string, name: string}, label: {id: string, name: string}}>
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
With `--dry-run`: a receipt object
|
|
580
|
+
|
|
581
|
+
```text
|
|
582
|
+
operation: string
|
|
583
|
+
dryRun: boolean
|
|
584
|
+
target: {id: string, identifier: string} | null
|
|
585
|
+
input: object
|
|
586
|
+
changed: boolean
|
|
587
|
+
mutationSent: boolean
|
|
588
|
+
groups: Array<{group: {id: string, name: string}, label: {id: string, name: string}}>
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
With `--full-result`: a receipt object
|
|
592
|
+
|
|
593
|
+
```text
|
|
594
|
+
receipt: {id: string, identifier: string, changed: boolean, mutationSent: boolean, groups: Array<{group: {id: string, name: string}, label: {id: string, name: string}}>}
|
|
595
|
+
resource: {id: string, identifier: string, title: string, description: string | null, priority: number, priorityLabel: string, estimate: number | null, url: string, branchName: string, dueDate: string | null, createdAt: string, updatedAt: string, archivedAt: string | null, trashed: boolean, startedAt: string | null, completedAt: string | null, canceledAt: string | null, state: {id: string, name: string, type: string} | null, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null, team: {id: string, key: string, name: string} | null, project: {id: string, name: string} | null, milestone: {id: string, name: string} | null, cycle: {id: string, number: number, name: string | null} | null, parent: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null} | null, children: Array<{id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}>, labels: Array<{id: string, name: string}>, subscribers: Array<{id: string, displayName: string}>, attachments: Array<{id: string, title: string, url: string, subtitle: string | null, sourceType: string | null, createdAt: string}>, documents: Array<{id: string, title: string, slugId: string, url: string, createdAt: string, updatedAt: string}>, relations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, inverseRelations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, comments: Array<{id: string, body: string, url: string, createdAt: string, editedAt: string | null, resolvedAt: string | null, parent: {id: string} | null, user: {id: string, displayName: string} | null, externalUser: {id: string, displayName: string} | null, resolvingCommentId: string | null, resolvingUser: {id: string, displayName: string} | null}>}
|
|
596
|
+
priorState: Array<{group: {id: string, name: string}, labels: Array<{id: string, name: string}>}>
|
|
597
|
+
verified: boolean
|
|
598
|
+
```
|
|
599
|
+
|
|
489
600
|
### `linear issue list`
|
|
490
601
|
|
|
491
602
|
List issues with filters
|
|
@@ -496,24 +607,24 @@ Aliases: `ls`, `query`
|
|
|
496
607
|
linear issue list [options]
|
|
497
608
|
```
|
|
498
609
|
|
|
499
|
-
| Option | Description
|
|
500
|
-
| ------------------------ |
|
|
501
|
-
| `-t, --team <key>` | filter by team key (repeatable; default: configured team)
|
|
502
|
-
| `-s, --state <name>` | filter by workflow state name/type (repeatable)
|
|
503
|
-
| `-a, --assignee <who>` | filter by assignee (me\|email\|name)
|
|
504
|
-
| `-U, --unassigned` | only issues with no assignee
|
|
505
|
-
| `-p, --project <name>` | filter by project
|
|
506
|
-
| `--project-label <name>` | filter by the project's label (excludes --project)
|
|
507
|
-
| `--milestone <name>` | filter by project milestone
|
|
508
|
-
| `-l, --label <name>` | filter by label (repeat to narrow)
|
|
509
|
-
| `-P, --priority <0-4>` | filter by priority
|
|
510
|
-
| `--cycle <n>` | cycle number, name, id, or 'current'
|
|
511
|
-
| `--created-after <date>` | only issues created at/after a date (YYYY-MM-DD)
|
|
512
|
-
| `--updated-after <date>` | only issues updated at/after a date (YYYY-MM-DD)
|
|
513
|
-
| `--all-teams` | search every team, ignoring the default team
|
|
514
|
-
| `--include-archived` | include archived
|
|
515
|
-
| `--query <text>` | full-text search
|
|
516
|
-
| `--sort <field>` | sort order
|
|
610
|
+
| Option | Description |
|
|
611
|
+
| ------------------------ | -------------------------------------------------------------------- |
|
|
612
|
+
| `-t, --team <key>` | filter by team key (repeatable; default: configured team) |
|
|
613
|
+
| `-s, --state <name>` | filter by workflow state name/type (repeatable) |
|
|
614
|
+
| `-a, --assignee <who>` | filter by assignee (me\|email\|name) |
|
|
615
|
+
| `-U, --unassigned` | only issues with no assignee |
|
|
616
|
+
| `-p, --project <name>` | filter by project |
|
|
617
|
+
| `--project-label <name>` | filter by the project's label (excludes --project) |
|
|
618
|
+
| `--milestone <name>` | filter by project milestone |
|
|
619
|
+
| `-l, --label <name>` | filter by label (repeat to narrow) |
|
|
620
|
+
| `-P, --priority <0-4>` | filter by priority |
|
|
621
|
+
| `--cycle <n>` | cycle number, name, id, or 'current' |
|
|
622
|
+
| `--created-after <date>` | only issues created at/after a date (YYYY-MM-DD) |
|
|
623
|
+
| `--updated-after <date>` | only issues updated at/after a date (YYYY-MM-DD) |
|
|
624
|
+
| `--all-teams` | search every team, ignoring the default team |
|
|
625
|
+
| `--include-archived` | include archived resources (the API may also return trashed records) |
|
|
626
|
+
| `--query <text>` | full-text search |
|
|
627
|
+
| `--sort <field>` | sort order |
|
|
517
628
|
|
|
518
629
|
**Output (`--json`)**: a bare array of objects
|
|
519
630
|
|
|
@@ -547,23 +658,23 @@ List your unstarted issues (--all-states for every state)
|
|
|
547
658
|
linear issue mine [options]
|
|
548
659
|
```
|
|
549
660
|
|
|
550
|
-
| Option | Description
|
|
551
|
-
| ------------------------ |
|
|
552
|
-
| `-t, --team <key>` | filter by team key (repeatable; default: configured team)
|
|
553
|
-
| `-s, --state <name>` | filter by workflow state name/type (repeatable)
|
|
554
|
-
| `-p, --project <name>` | filter by project
|
|
555
|
-
| `--project-label <name>` | filter by the project's label (excludes --project)
|
|
556
|
-
| `--milestone <name>` | filter by project milestone
|
|
557
|
-
| `-l, --label <name>` | filter by label (repeat to narrow)
|
|
558
|
-
| `-P, --priority <0-4>` | filter by priority
|
|
559
|
-
| `--cycle <n>` | cycle number, name, id, or 'current'
|
|
560
|
-
| `--created-after <date>` | only issues created at/after a date (YYYY-MM-DD)
|
|
561
|
-
| `--updated-after <date>` | only issues updated at/after a date (YYYY-MM-DD)
|
|
562
|
-
| `--all-teams` | search every team, ignoring the default team
|
|
563
|
-
| `--include-archived` | include archived
|
|
564
|
-
| `--query <text>` | full-text search
|
|
565
|
-
| `--sort <field>` | sort order
|
|
566
|
-
| `--all-states` | include every workflow state, not just unstarted
|
|
661
|
+
| Option | Description |
|
|
662
|
+
| ------------------------ | -------------------------------------------------------------------- |
|
|
663
|
+
| `-t, --team <key>` | filter by team key (repeatable; default: configured team) |
|
|
664
|
+
| `-s, --state <name>` | filter by workflow state name/type (repeatable) |
|
|
665
|
+
| `-p, --project <name>` | filter by project |
|
|
666
|
+
| `--project-label <name>` | filter by the project's label (excludes --project) |
|
|
667
|
+
| `--milestone <name>` | filter by project milestone |
|
|
668
|
+
| `-l, --label <name>` | filter by label (repeat to narrow) |
|
|
669
|
+
| `-P, --priority <0-4>` | filter by priority |
|
|
670
|
+
| `--cycle <n>` | cycle number, name, id, or 'current' |
|
|
671
|
+
| `--created-after <date>` | only issues created at/after a date (YYYY-MM-DD) |
|
|
672
|
+
| `--updated-after <date>` | only issues updated at/after a date (YYYY-MM-DD) |
|
|
673
|
+
| `--all-teams` | search every team, ignoring the default team |
|
|
674
|
+
| `--include-archived` | include archived resources (the API may also return trashed records) |
|
|
675
|
+
| `--query <text>` | full-text search |
|
|
676
|
+
| `--sort <field>` | sort order |
|
|
677
|
+
| `--all-states` | include every workflow state, not just unstarted |
|
|
567
678
|
|
|
568
679
|
**Output (`--json`)**: a bare array of objects
|
|
569
680
|
|
|
@@ -664,23 +775,23 @@ Full-text search across issues (scoped to the default team; --all-teams widens)
|
|
|
664
775
|
linear issue search [options] <text>
|
|
665
776
|
```
|
|
666
777
|
|
|
667
|
-
| Option | Description
|
|
668
|
-
| ------------------------ |
|
|
669
|
-
| `-t, --team <key>` | filter by team key (repeatable; default: configured team)
|
|
670
|
-
| `-s, --state <name>` | filter by workflow state name/type (repeatable)
|
|
671
|
-
| `-a, --assignee <who>` | filter by assignee (me\|email\|name)
|
|
672
|
-
| `-U, --unassigned` | only issues with no assignee
|
|
673
|
-
| `-p, --project <name>` | filter by project
|
|
674
|
-
| `--project-label <name>` | filter by the project's label (excludes --project)
|
|
675
|
-
| `--milestone <name>` | filter by project milestone
|
|
676
|
-
| `-l, --label <name>` | filter by label (repeat to narrow)
|
|
677
|
-
| `-P, --priority <0-4>` | filter by priority
|
|
678
|
-
| `--cycle <n>` | cycle number, name, id, or 'current'
|
|
679
|
-
| `--created-after <date>` | only issues created at/after a date (YYYY-MM-DD)
|
|
680
|
-
| `--updated-after <date>` | only issues updated at/after a date (YYYY-MM-DD)
|
|
681
|
-
| `--all-teams` | search every team, ignoring the default team
|
|
682
|
-
| `--include-archived` | include archived
|
|
683
|
-
| `--search-comments` | match comment bodies as well as titles and descriptions
|
|
778
|
+
| Option | Description |
|
|
779
|
+
| ------------------------ | -------------------------------------------------------------------- |
|
|
780
|
+
| `-t, --team <key>` | filter by team key (repeatable; default: configured team) |
|
|
781
|
+
| `-s, --state <name>` | filter by workflow state name/type (repeatable) |
|
|
782
|
+
| `-a, --assignee <who>` | filter by assignee (me\|email\|name) |
|
|
783
|
+
| `-U, --unassigned` | only issues with no assignee |
|
|
784
|
+
| `-p, --project <name>` | filter by project |
|
|
785
|
+
| `--project-label <name>` | filter by the project's label (excludes --project) |
|
|
786
|
+
| `--milestone <name>` | filter by project milestone |
|
|
787
|
+
| `-l, --label <name>` | filter by label (repeat to narrow) |
|
|
788
|
+
| `-P, --priority <0-4>` | filter by priority |
|
|
789
|
+
| `--cycle <n>` | cycle number, name, id, or 'current' |
|
|
790
|
+
| `--created-after <date>` | only issues created at/after a date (YYYY-MM-DD) |
|
|
791
|
+
| `--updated-after <date>` | only issues updated at/after a date (YYYY-MM-DD) |
|
|
792
|
+
| `--all-teams` | search every team, ignoring the default team |
|
|
793
|
+
| `--include-archived` | include archived resources (the API may also return trashed records) |
|
|
794
|
+
| `--search-comments` | match comment bodies as well as titles and descriptions |
|
|
684
795
|
|
|
685
796
|
**Output (`--json`)**: a bare array of objects
|
|
686
797
|
|
|
@@ -817,26 +928,30 @@ Aliases: `edit`
|
|
|
817
928
|
linear issue update [options] [id]
|
|
818
929
|
```
|
|
819
930
|
|
|
820
|
-
| Option | Description
|
|
821
|
-
| --------------------------- |
|
|
822
|
-
| `--title <title>` | new title
|
|
823
|
-
| `-d, --description <text>` | new description
|
|
824
|
-
| `--description-file <path>` | read description from a file ('-' = stdin)
|
|
825
|
-
| `-t, --team <key>` | move the issue to another team (changes its identifier)
|
|
826
|
-
| `-a, --assignee <who>` | assignee (me\|email\|name\|id)
|
|
827
|
-
|
|
|
828
|
-
| `-
|
|
829
|
-
| `-
|
|
830
|
-
|
|
|
831
|
-
| `--
|
|
832
|
-
| `--
|
|
833
|
-
| `--
|
|
834
|
-
| `--
|
|
835
|
-
|
|
|
836
|
-
|
|
|
837
|
-
| `--
|
|
838
|
-
| `--
|
|
839
|
-
| `--
|
|
931
|
+
| Option | Description |
|
|
932
|
+
| --------------------------- | -------------------------------------------------------------- |
|
|
933
|
+
| `--title <title>` | new title |
|
|
934
|
+
| `-d, --description <text>` | new description |
|
|
935
|
+
| `--description-file <path>` | read description from a file ('-' = stdin) |
|
|
936
|
+
| `-t, --team <key>` | move the issue to another team (changes its identifier) |
|
|
937
|
+
| `-a, --assignee <who>` | assignee (me\|email\|name\|id) |
|
|
938
|
+
| `--delegate <agent>` | delegate to an eligible agent app user (name or id) |
|
|
939
|
+
| `-s, --state <name>` | workflow state name or type |
|
|
940
|
+
| `-P, --priority <0-4>` | priority |
|
|
941
|
+
| `-p, --project <name>` | project name or id |
|
|
942
|
+
| `--milestone <name>` | project milestone |
|
|
943
|
+
| `--cycle <n>` | cycle number, name, id, or 'current' |
|
|
944
|
+
| `--estimate <n>` | estimate points |
|
|
945
|
+
| `--parent <id>` | parent issue id |
|
|
946
|
+
| `--due <date>` | due date (YYYY-MM-DD) |
|
|
947
|
+
| `-l, --label <name>` | replace all labels (repeatable / comma-separated) |
|
|
948
|
+
| `--add-label <name>` | add a label (repeatable) |
|
|
949
|
+
| `--remove-label <name>` | remove a label (repeatable) |
|
|
950
|
+
| `--unassign` | clear the assignee |
|
|
951
|
+
| `--clear-delegate` | remove the agent delegate |
|
|
952
|
+
| `--clear-cycle` | remove the issue from its cycle |
|
|
953
|
+
| `--dry-run` | resolve and show the delegation mutation input without writing |
|
|
954
|
+
| `--full-result` | read back and verify the resulting delegate |
|
|
840
955
|
|
|
841
956
|
**Output (`--json`)**: a receipt object
|
|
842
957
|
|
|
@@ -846,6 +961,37 @@ identifier: string
|
|
|
846
961
|
url: string
|
|
847
962
|
```
|
|
848
963
|
|
|
964
|
+
With `--delegate`: the same, plus:
|
|
965
|
+
|
|
966
|
+
```text
|
|
967
|
+
assignee: {id: string, displayName: string, email: string} | null
|
|
968
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
969
|
+
```
|
|
970
|
+
|
|
971
|
+
With `--clear-delegate`: the same, plus:
|
|
972
|
+
|
|
973
|
+
```text
|
|
974
|
+
assignee: {id: string, displayName: string, email: string} | null
|
|
975
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
With `--dry-run`: a receipt object
|
|
979
|
+
|
|
980
|
+
```text
|
|
981
|
+
operation: string
|
|
982
|
+
dryRun: boolean
|
|
983
|
+
target: {id: string, identifier: string} | null
|
|
984
|
+
input: object
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
With `--full-result`: a receipt object
|
|
988
|
+
|
|
989
|
+
```text
|
|
990
|
+
receipt: {id: string, identifier: string, url: string, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null}
|
|
991
|
+
resource: {id: string, identifier: string, title: string, description: string | null, priority: number, priorityLabel: string, estimate: number | null, url: string, branchName: string, dueDate: string | null, createdAt: string, updatedAt: string, archivedAt: string | null, trashed: boolean, startedAt: string | null, completedAt: string | null, canceledAt: string | null, state: {id: string, name: string, type: string} | null, assignee: {id: string, displayName: string, email: string} | null, delegate: {id: string, displayName: string, name: string} | null, team: {id: string, key: string, name: string} | null, project: {id: string, name: string} | null, milestone: {id: string, name: string} | null, cycle: {id: string, number: number, name: string | null} | null, parent: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null} | null, children: Array<{id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}>, labels: Array<{id: string, name: string}>, subscribers: Array<{id: string, displayName: string}>, attachments: Array<{id: string, title: string, url: string, subtitle: string | null, sourceType: string | null, createdAt: string}>, documents: Array<{id: string, title: string, slugId: string, url: string, createdAt: string, updatedAt: string}>, relations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, inverseRelations: Array<{id: string, type: string, issue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}, relatedIssue: {id: string, identifier: string, title: string, state: {id: string, name: string, type: string} | null}}>, comments: Array<{id: string, body: string, url: string, createdAt: string, editedAt: string | null, resolvedAt: string | null, parent: {id: string} | null, user: {id: string, displayName: string} | null, externalUser: {id: string, displayName: string} | null, resolvingCommentId: string | null, resolvingUser: {id: string, displayName: string} | null}>}
|
|
992
|
+
verified: boolean
|
|
993
|
+
```
|
|
994
|
+
|
|
849
995
|
### `linear issue url`
|
|
850
996
|
|
|
851
997
|
Print the issue URL
|
|
@@ -897,6 +1043,7 @@ completedAt: string | null
|
|
|
897
1043
|
canceledAt: string | null
|
|
898
1044
|
state: {id: string, name: string, type: string} | null
|
|
899
1045
|
assignee: {id: string, displayName: string, email: string} | null
|
|
1046
|
+
delegate: {id: string, displayName: string, name: string} | null
|
|
900
1047
|
team: {id: string, key: string, name: string} | null
|
|
901
1048
|
project: {id: string, name: string} | null
|
|
902
1049
|
milestone: {id: string, name: string} | null
|
|
@@ -43,9 +43,9 @@ Aliases: `ls`
|
|
|
43
43
|
linear notification list [options]
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
| Option | Description
|
|
47
|
-
| -------------------- |
|
|
48
|
-
| `--include-archived` | include archived
|
|
46
|
+
| Option | Description |
|
|
47
|
+
| -------------------- | -------------------------------------------------------------------- |
|
|
48
|
+
| `--include-archived` | include archived resources (the API may also return trashed records) |
|
|
49
49
|
|
|
50
50
|
**Output (`--json`)**: a bare array of objects
|
|
51
51
|
|
|
@@ -39,6 +39,7 @@ createdAt: string
|
|
|
39
39
|
updatedAt: string
|
|
40
40
|
completedAt: string | null
|
|
41
41
|
archivedAt: string | null
|
|
42
|
+
trashed: boolean
|
|
42
43
|
lead: {id: string, displayName: string, email: string} | null
|
|
43
44
|
teams: Array<{id: string, key: string, name: string}>
|
|
44
45
|
members: Array<{id: string, displayName: string, email: string}>
|
|
@@ -125,10 +126,11 @@ Aliases: `ls`
|
|
|
125
126
|
linear project list [options]
|
|
126
127
|
```
|
|
127
128
|
|
|
128
|
-
| Option
|
|
129
|
-
|
|
|
130
|
-
| `--state <name>`
|
|
131
|
-
| `--all-teams`
|
|
129
|
+
| Option | Description |
|
|
130
|
+
| -------------------- | -------------------------------------------------------------------- |
|
|
131
|
+
| `--state <name>` | filter by status name or type (e.g. 'In QA', started) |
|
|
132
|
+
| `--all-teams` | every team's projects, ignoring the default team |
|
|
133
|
+
| `--include-archived` | include archived resources (the API may also return trashed records) |
|
|
132
134
|
|
|
133
135
|
**Output (`--json`)**: a bare array of objects
|
|
134
136
|
|
|
@@ -142,6 +144,8 @@ startDate: string | null
|
|
|
142
144
|
targetDate: string | null
|
|
143
145
|
status: {name: string} | null
|
|
144
146
|
lead: {displayName: string} | null
|
|
147
|
+
archivedAt: string | null
|
|
148
|
+
trashed: boolean
|
|
145
149
|
```
|
|
146
150
|
|
|
147
151
|
### `linear project milestones`
|
|
@@ -228,6 +232,7 @@ createdAt: string
|
|
|
228
232
|
updatedAt: string
|
|
229
233
|
completedAt: string | null
|
|
230
234
|
archivedAt: string | null
|
|
235
|
+
trashed: boolean
|
|
231
236
|
lead: {id: string, displayName: string, email: string} | null
|
|
232
237
|
teams: Array<{id: string, key: string, name: string}>
|
|
233
238
|
members: Array<{id: string, displayName: string, email: string}>
|
package/src/cli.ts
CHANGED
package/src/commands/comment.ts
CHANGED
|
@@ -32,12 +32,12 @@ const ROW_COLUMNS: Column<svc.CommentRow>[] = [
|
|
|
32
32
|
/** Options for a mounted copy of the shared verbs. */
|
|
33
33
|
interface MountOptions {
|
|
34
34
|
/** Register the short aliases (`ls`, `edit`, `rm`). Off under `issue comment`. */
|
|
35
|
-
|
|
35
|
+
shortAliases?: boolean;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function buildList(o: MountOptions): Command {
|
|
39
39
|
const cmd = new Command("list").argument("<issue>").description("List comments on an issue");
|
|
40
|
-
if (o.
|
|
40
|
+
if (o.shortAliases !== false) cmd.alias("ls");
|
|
41
41
|
return cmd.action(
|
|
42
42
|
action(async (ctx: Context, _opts, issueArg: string) => {
|
|
43
43
|
const rows = await svc.listComments(ctx.client, issueArg, ctx.limit);
|
|
@@ -48,6 +48,7 @@ function buildList(o: MountOptions): Command {
|
|
|
48
48
|
|
|
49
49
|
function buildAdd(_o: MountOptions): Command {
|
|
50
50
|
return new Command("add")
|
|
51
|
+
.alias("create")
|
|
51
52
|
.argument("<issue>")
|
|
52
53
|
.argument("[body]")
|
|
53
54
|
.description("Add a comment to an issue (images uploaded with --attach render inline)")
|
|
@@ -129,7 +130,7 @@ function buildUpdate(o: MountOptions): Command {
|
|
|
129
130
|
"prepend a real Linear mention (name, email, me, or id; repeatable)",
|
|
130
131
|
collectArray,
|
|
131
132
|
);
|
|
132
|
-
if (o.
|
|
133
|
+
if (o.shortAliases !== false) cmd.alias("edit");
|
|
133
134
|
return cmd.action(
|
|
134
135
|
action(async (ctx: Context, opts, commentId: string, bodyArg?: string) => {
|
|
135
136
|
// Fetch the comment first: the editor opens ON the current body (so
|
|
@@ -161,7 +162,7 @@ function buildUpdate(o: MountOptions): Command {
|
|
|
161
162
|
|
|
162
163
|
function buildDelete(o: MountOptions): Command {
|
|
163
164
|
const cmd = new Command("delete").argument("<commentId>").description("Delete a comment");
|
|
164
|
-
if (o.
|
|
165
|
+
if (o.shortAliases !== false) cmd.alias("rm");
|
|
165
166
|
return cmd.action(
|
|
166
167
|
action(async (ctx: Context, _opts, commentId: string) => {
|
|
167
168
|
if (!(await confirmDestructive(ctx, `Delete comment ${commentId}?`))) return;
|
|
@@ -250,11 +251,12 @@ export function registerComment(program: Command): void {
|
|
|
250
251
|
* command, which keeps its own `[id] [body]` "add a comment" behavior for every
|
|
251
252
|
* other operand. The short aliases (`ls`, `edit`, `rm`) are deliberately NOT
|
|
252
253
|
* registered here: each subcommand name shadows a one-word comment body under
|
|
253
|
-
* the parent
|
|
254
|
-
*
|
|
254
|
+
* the parent. `create` is the sole additional collision because agents commonly
|
|
255
|
+
* infer it from other resource mutations; accepting that spelling is safer than
|
|
256
|
+
* rejecting an intended comment mutation.
|
|
255
257
|
*/
|
|
256
258
|
export function registerIssueCommentGroup(issueComment: Command): void {
|
|
257
259
|
for (const build of Object.values(SHARED_COMMENT_VERBS)) {
|
|
258
|
-
issueComment.addCommand(build({
|
|
260
|
+
issueComment.addCommand(build({ shortAliases: false }));
|
|
259
261
|
}
|
|
260
262
|
}
|
|
@@ -10,14 +10,26 @@ import { Command, Option } from "commander";
|
|
|
10
10
|
import { action } from "../lib/action.js";
|
|
11
11
|
import { resolveBody } from "../lib/body.js";
|
|
12
12
|
import { confirmDestructive, promptInput } from "../lib/prompt.js";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
parseList,
|
|
15
|
+
parseIntOption,
|
|
16
|
+
addAliasOption,
|
|
17
|
+
readAlias,
|
|
18
|
+
addIncludeArchivedOption,
|
|
19
|
+
} from "../lib/options.js";
|
|
14
20
|
import type { Context } from "../context.js";
|
|
15
21
|
import * as svc from "../services/initiative.js";
|
|
16
22
|
import type { Column } from "../output/table.js";
|
|
23
|
+
import { lifecycleSuffix } from "../output/lifecycle.js";
|
|
17
24
|
|
|
18
25
|
const ROW_COLUMNS: Column<svc.InitiativeRow>[] = [
|
|
19
26
|
{ key: "name", header: "Name", value: (r) => r.name, max: 40 },
|
|
20
|
-
{
|
|
27
|
+
{
|
|
28
|
+
key: "status",
|
|
29
|
+
header: "Status",
|
|
30
|
+
value: (r) => `${r.status ?? "—"}${lifecycleSuffix(r)}`,
|
|
31
|
+
max: 24,
|
|
32
|
+
},
|
|
21
33
|
{
|
|
22
34
|
key: "priority",
|
|
23
35
|
header: "Pri",
|
|
@@ -34,7 +46,7 @@ export function registerInitiative(program: Command): void {
|
|
|
34
46
|
.description("Work with initiatives");
|
|
35
47
|
|
|
36
48
|
// list --------------------------------------------------------------------
|
|
37
|
-
initiative
|
|
49
|
+
const list = initiative
|
|
38
50
|
.command("list")
|
|
39
51
|
.alias("ls")
|
|
40
52
|
.description("List workspace initiatives (every status unless --status narrows)")
|
|
@@ -42,7 +54,6 @@ export function registerInitiative(program: Command): void {
|
|
|
42
54
|
// in the tree, and a short flag means one thing everywhere here.
|
|
43
55
|
.option("--status <name>", "filter by status (Planned, Active, Completed, Canceled, Proposed)")
|
|
44
56
|
.option("--owner <who>", "filter by owner (me|email|name|id)")
|
|
45
|
-
.option("--archived", "include archived initiatives")
|
|
46
57
|
// The reference CLI lists Active only and needs `--all-statuses` to widen;
|
|
47
58
|
// this list is every status already, so the flag is accepted as the no-op
|
|
48
59
|
// it is here rather than failing a transplanted script.
|
|
@@ -52,11 +63,13 @@ export function registerInitiative(program: Command): void {
|
|
|
52
63
|
const rows = await svc.listInitiatives(ctx.client, ctx.limit, {
|
|
53
64
|
status: opts.status,
|
|
54
65
|
owner: opts.owner,
|
|
55
|
-
|
|
66
|
+
includeArchived: !!readAlias<boolean>(opts, "--include-archived", "--archived"),
|
|
56
67
|
});
|
|
57
68
|
ctx.output.list(rows, ROW_COLUMNS, rows);
|
|
58
69
|
}),
|
|
59
70
|
);
|
|
71
|
+
addIncludeArchivedOption(list);
|
|
72
|
+
list.addOption(new Option("--archived", "compatibility alias of --include-archived"));
|
|
60
73
|
|
|
61
74
|
// view --------------------------------------------------------------------
|
|
62
75
|
initiative
|
|
@@ -68,7 +81,11 @@ export function registerInitiative(program: Command): void {
|
|
|
68
81
|
const detail = await svc.getInitiativeDetail(ctx.client, idArg);
|
|
69
82
|
ctx.output.detail(detail, [
|
|
70
83
|
["Initiative", detail.name],
|
|
71
|
-
[
|
|
84
|
+
[
|
|
85
|
+
"Trashed",
|
|
86
|
+
detail.trashed ? `YES (deleted ${detail.archivedAt ?? "at an unknown time"})` : null,
|
|
87
|
+
],
|
|
88
|
+
["Archived", !detail.trashed && detail.archivedAt ? `YES (${detail.archivedAt})` : null],
|
|
72
89
|
["Status", detail.status],
|
|
73
90
|
["Priority", detail.priority ? detail.priorityLabel : null],
|
|
74
91
|
["Labels", detail.labels.length ? detail.labels.join(", ") : null],
|