From 8eae8f1e699d89514339f4700deddcd45bcf6f3c Mon Sep 17 00:00:00 2001 From: Peter Schilling Date: Wed, 5 Aug 2026 14:29:48 -0700 Subject: [PATCH] Add --add-label and --remove-label to issue update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reporter asked for a way to detach a label from one issue without deleting it team-wide, believing --label was additive. It actually replaces the issue's entire label set (IssueUpdateInput.labelIds), so the gap was wider than reported: adding one label clobbered the rest. Rather than only the suggested --remove-label, this maps both --add-label and --remove-label onto the API's addedLabelIds/ removedLabelIds (one atomic mutation, no read-modify-write). --label keeps its documented replace semantics for existing scripts, with help text that now says so. Flag names match gh issue edit, the surface users and agents reach for first. A --clear-labels flag was considered (an empty label set is currently inexpressible in one command) and deliberately deferred: adding a flag later is backwards compatible, removing one is breaking, and nothing has asked for clear-all yet. Invalid combinations error before any network call: --label with incremental flags, the same resolved label ID in both add and remove, and --team moves combined with incremental flags (label names resolve against the destination team, which would make source-team labels silently unresolvable). Live QA confirmed removing an unattached label is rejected by Linear's API ("Label is not on issue "), not a silent no-op — surfaced as-is, consistent with the repo's explicit-input-errors philosophy. The reporter's alternative ask (label rename) is deferred: it is team-wide and would not solve the per-issue detach workflow. Github-Issue: Fixes #258 Github-Issue-Url: https://github.com/schpet/linear-cli/issues/258 --- docs/usage.md | 16 + skills/linear-cli/SKILL.md | 5 +- skills/linear-cli/SKILL.template.md | 5 +- skills/linear-cli/references/issue.md | 6 +- .../references/organization-features.md | 14 +- src/commands/issue/issue-update.ts | 82 ++- .../__snapshots__/issue-update.test.ts.snap | 124 ++++- test/commands/issue/issue-update.test.ts | 490 ++++++++++++++++++ 8 files changed, 726 insertions(+), 16 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 7a19e60d..307905ff 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -159,6 +159,22 @@ update a specific issue: linear issue update TEAM-123 ``` +change labels: + +```bash +# Add a label, keeping existing labels +linear issue update TEAM-123 --add-label bug + +# Remove a label from this issue (does not delete it from the team) +linear issue update TEAM-123 --remove-label sprint-42 + +# Swap labels atomically in one update +linear issue update TEAM-123 --remove-label sprint-42 --add-label sprint-43 + +# Replace the entire label set +linear issue update TEAM-123 --label bug --label frontend +``` + #### other issue commands get issue id from current git branch: diff --git a/skills/linear-cli/SKILL.md b/skills/linear-cli/SKILL.md index 024a2fff..eadf0ee9 100644 --- a/skills/linear-cli/SKILL.md +++ b/skills/linear-cli/SKILL.md @@ -61,7 +61,10 @@ Write multi-line markdown to a file and pass `--description-file` (see the markd ```bash linear issue update ENG-123 --state "In Review" --assignee sam linear issue update ENG-123 --unassign -linear issue update ENG-123 --label infra --label security # replaces the label set +linear issue update ENG-123 --add-label security # add, keep existing labels +linear issue update ENG-123 --remove-label sprint-42 # detach; does not delete the label +linear issue update ENG-123 --remove-label sprint-42 --add-label sprint-43 # atomic swap +linear issue update ENG-123 --label infra --label security # replaces the label set ``` ### Add a comment diff --git a/skills/linear-cli/SKILL.template.md b/skills/linear-cli/SKILL.template.md index d65a2de1..dc69dc4d 100644 --- a/skills/linear-cli/SKILL.template.md +++ b/skills/linear-cli/SKILL.template.md @@ -61,7 +61,10 @@ Write multi-line markdown to a file and pass `--description-file` (see the markd ```bash linear issue update ENG-123 --state "In Review" --assignee sam linear issue update ENG-123 --unassign -linear issue update ENG-123 --label infra --label security # replaces the label set +linear issue update ENG-123 --add-label security # add, keep existing labels +linear issue update ENG-123 --remove-label sprint-42 # detach; does not delete the label +linear issue update ENG-123 --remove-label sprint-42 --add-label sprint-43 # atomic swap +linear issue update ENG-123 --label infra --label security # replaces the label set ``` ### Add a comment diff --git a/skills/linear-cli/references/issue.md b/skills/linear-cli/references/issue.md index 1131c17f..44591254 100644 --- a/skills/linear-cli/references/issue.md +++ b/skills/linear-cli/references/issue.md @@ -581,7 +581,11 @@ Options: --estimate - Points estimate of the issue -d, --description - Description of the issue --description-file - Read description from a file (preferred for markdown content) - -l, --label