Skip to content

feat(issue): add lc issue status command - #123

Merged
bougyman merged 4 commits into
mainfrom
CRY-47-add-issue-status-command
Aug 16, 2026
Merged

feat(issue): add lc issue status command#123
bougyman merged 4 commits into
mainfrom
CRY-47-add-issue-status-command

Conversation

@bougyman

Copy link
Copy Markdown
Member

Summary

  • Adds lc issue status ISSUE_ID to change an issue's workflow state
  • --status/-s sets the state by name (case-insensitive exact match, then unique prefix); prompts interactively when omitted
  • --comment/-m adds a comment alongside the status change
  • "s" subcommand alias mirrors other single-letter issue aliases (c, d, l, u)
  • Resolves ISSUE_ID via the existing expand_issue_id/1 convention
  • Errors clearly on unknown or ambiguous status names (exit 22 via {:smells_bad, …})
  • JSON output emits the updated issue struct only; text mode adds a confirmation line

Implementation

  • New :set_status Ash action on LinearCli.Linear.Issue with a dedicated LinearCli.Linear.Issue.Update.SetStatus manual update module (mirrors the pattern of :close, :assign, :attach_to_project)
  • set_issue_status/2 domain code interface in LinearCli.Linear
  • status subcommand entry in the Optimus spec with ISSUE_ID positional arg and --status/--comment options
  • Commands.issue_status/1 orchestrates the full flow: expand id → fetch issue → fetch team states → resolve target state → optional comment → transition → display

Test plan

  • Exact name match (case-insensitive via --status done)
  • Short -s flag
  • Unique prefix match (e.g. --status in → "In Progress")
  • Unknown status name → exit 22 + clear message
  • Ambiguous prefix → exit 22 + clear message
  • --comment/-m adds comment before transitioning
  • Interactive selection (no --status): prompts sorted by position
  • --output json emits parseable JSON only
  • "s" alias routes correctly

Closes https://linear.app/cryptokairos/issue/CRY-47/add-lc-issue-status-command

🤖 Generated with Claude Code

Adds `lc issue status ISSUE_ID` to change an issue's workflow state.

- --status/-s sets the state by name (case-insensitive, prefix match);
  prompts interactively when omitted
- --comment/-m adds a comment alongside the status change
- "s" subcommand alias mirrors the other single-letter issue aliases
- Resolves ISSUE_ID via the existing expand_issue_id/1 convention
- Errors clearly on unknown or ambiguous status names (exit 22)
- JSON output mode emits the updated issue struct; text mode adds a
  confirmation line
- Backed by a new :set_status Ash action on LinearCli.Linear.Issue
  (LinearCli.Linear.Issue.Update.SetStatus manual update module) and a
  set_issue_status/2 domain code interface
- 9 new tests covering: exact match, -s short flag, prefix match,
  unknown name, ambiguous name, --comment, interactive selection,
  --output json, and alias routing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 16, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread app/lib/linear_cli/cli/commands.ex
…eline steps

Replace nested case statements with use_prefix_matches_if_empty/3 and
resolve_state_matches/3 helpers, eliminating duplicate ambiguous-match
branches and reducing cyclomatic complexity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bougyman

Copy link
Copy Markdown
Member Author

Addressed the review comment: replaced the nested case in resolve_target_state/2 with the pipeline-based approach you suggested. Now splits into three named helpers — use_prefix_matches_if_empty/3 (exact-match fallback) and resolve_state_matches/3 (three-clause pattern match on list shape) — eliminating the duplicated ambiguous-match branch and the cyclomatic complexity. All 25 issue_commands tests still pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bougyman

Copy link
Copy Markdown
Member Author

Fixed the CI failure: ran mix format on the two files that were flagged (commands.ex and issue_commands_test.exs). Long map literals and one long if were broken onto multiple lines per the formatter's 98-column rule. All 25 issue_commands tests still pass. Commit: d274a68.

@bougyman

Copy link
Copy Markdown
Member Author

Code Review (Run 4)

Branch: CRY-47-add-issue-status-command (3 commits: b8a7b7e, 11d27c7, d274a68)
Reviewer: Independent code review agent — no prior context on this issue.

Summary

The implementation adds lc issue status ISSUE_ID backed by a new :set_status Ash action. Code is clean, idiomatic, and follows established project patterns. All 248 non-environment-specific tests pass. Formatting and compilation are clean.

Issues Found

None critical. None major.

Minor:

  1. Dead stub_responses call in test (app/test/linear_cli/cli/issue_commands_test.exs:559-561)
    The first test ("--status sets the workflow state by exact name") calls stub_responses/1 and then immediately overwrites it with a manual Req.Test.stub/2 two lines later. The stub_responses call is dead code — it has no effect. All other status tests correctly use only the manual stub. Suggest removing lines 559-561.

  2. @doc says "New command." (app/lib/linear_cli/cli/commands.ex:479)
    The phrase "New command." is temporal — it will stop being "new" and become stale. Consider removing or replacing with just the behavior description.

  3. No test for -m short form — The -s short form for --status has its own test, but -m for --comment does not. Optimus handles the mapping, so this is a framework guarantee, but adding a one-liner assertion would be consistent.

What Looks Good

  • Pipeline decomposition of resolve_target_state/2 into use_prefix_matches_if_empty/3 + resolve_state_matches/3 is clean idiomatic Elixir — multi-clause functions replacing nested case statements.
  • Ash action structure (SetStatus manual update module) follows the exact same pattern as Close, Assign, and AttachToProject. Consistent and composable.
  • Test coverage is thorough: exact match, prefix match, ambiguous match, unknown status, interactive selection, comment flow, JSON output, and alias routing — all covered with correct assertions.
  • Error semantics use {:error, {:smells_bad, msg}} consistently, mapping to exit 22 via the existing handle_error/3 path.
  • Subcommand alias "s" => "status" doesn't conflict with any existing alias.

Pre-existing Observation (not introduced by this PR)

The {:ok, [issue]} <- Linear.issues(...) pattern in the with chain (line 492) will fall through as {:ok, []} if the issue ID doesn't resolve, causing a CaseClauseError in run/3. This is the same pattern used in gimme_da_issue!/2 (issue_helpers.ex:442) — a pre-existing gap, not a regression.

Overall Assessment

Approve. The three minor items are cleanup nits, not blockers. The feature is correct, well-tested, and follows project conventions.

Drop dead stub_responses call in first status test (immediately
overridden by the manual Req.Test.stub below it). Strip temporal
"New command." opener from @doc — it stops being accurate on day 2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bougyman

Copy link
Copy Markdown
Member Author

Rework (Run 5)

Addressed the two minor cleanup items from code review:

  • app/lib/linear_cli/cli/commands.ex — Removed "New command." from @doc opener (temporal phrase that goes stale immediately)
  • app/test/linear_cli/cli/issue_commands_test.exs — Removed dead stub_responses([...]) call in the first status test (was unconditionally overwritten by the Req.Test.stub two lines below it)

Commit: 0431f97 (style(issue-status): remove review-noted clutter)
All 25 issue_commands tests pass.

@bougyman
bougyman merged commit 20d0158 into main Aug 16, 2026
2 checks passed
@bougyman
bougyman deleted the CRY-47-add-issue-status-command branch August 16, 2026 16:01
bougyman pushed a commit that referenced this pull request Aug 16, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.10.0](v1.9.1...v1.10.0)
(2026-08-16)


### Features

* **issue:** add lc issue status command
([#123](#123))
([20d0158](20d0158))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants