From 3ef77aef861fa84b0bbc2dfef07e5a200863ea36 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Thu, 20 Aug 2026 11:01:38 -0400 Subject: [PATCH 1/2] feat(EXT-5): show workflow status in compact and full issue listings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Display the workflow state name in brackets (e.g. [In Progress]) after the issue identifier in both compact and full text output. The state data was already fetched by the existing GraphQL query; this is a display-only change. Nil state is handled gracefully — the brackets are omitted when no state is present. Co-Authored-By: Claude Sonnet 4.6 --- app/lib/linear_cli/cli/display.ex | 3 +- .../linear_cli/cli/issue_commands_test.exs | 100 ++++++++++++++++++ .../linear_cli/cli/profile_defaults_test.exs | 1 + 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/app/lib/linear_cli/cli/display.ex b/app/lib/linear_cli/cli/display.ex index 301a140..d5a8538 100644 --- a/app/lib/linear_cli/cli/display.ex +++ b/app/lib/linear_cli/cli/display.ex @@ -68,7 +68,8 @@ defmodule LinearCli.CLI.Display do end defp issue_line(issue) do - basic = "#{String.pad_trailing(issue.identifier || "", 12)} #{issue.title}" + state = if issue.state, do: "[#{issue.state.name}] ", else: "" + basic = "#{String.pad_trailing(issue.identifier || "", 12)} #{state}#{issue.title}" if issue.assignee, do: "#{basic} (#{issue.assignee.name})", else: basic end diff --git a/app/test/linear_cli/cli/issue_commands_test.exs b/app/test/linear_cli/cli/issue_commands_test.exs index b89a884..f9a3927 100644 --- a/app/test/linear_cli/cli/issue_commands_test.exs +++ b/app/test/linear_cli/cli/issue_commands_test.exs @@ -73,6 +73,7 @@ defmodule LinearCli.CLI.IssueCommandsTest do "branchName" => "cry-1-fix-the-thing", "description" => "It is broken", "assignee" => nil, + "state" => %{"id" => "s1", "name" => "In Progress", "type" => "started"}, "team" => team_map(), "comments" => %{"nodes" => []} }, @@ -256,6 +257,49 @@ defmodule LinearCli.CLI.IssueCommandsTest do assert output =~ "CRY-1" end + test "compact listing shows workflow status name in brackets" do + Req.Test.stub(LinearCli.Api, fn conn -> + {:ok, body, conn} = Plug.Conn.read_body(conn) + Req.Test.json(conn, issues_response([issue_map()])) + end) + + output = capture_io(fn -> assert :ok = LinearCli.CLI.main(["issue", "list"]) end) + assert output =~ "[In Progress]" + assert output =~ "Fix the thing" + end + + test "compact listing omits status brackets when state is absent" do + Req.Test.stub(LinearCli.Api, fn conn -> + {:ok, body, conn} = Plug.Conn.read_body(conn) + Req.Test.json(conn, issues_response([issue_map(%{"state" => nil})])) + end) + + output = capture_io(fn -> assert :ok = LinearCli.CLI.main(["issue", "list"]) end) + assert output =~ "CRY-1" + refute output =~ "[" + end + + test "--full listing shows workflow status in the header line" do + Req.Test.stub(LinearCli.Api, fn conn -> + {:ok, body, conn} = Plug.Conn.read_body(conn) + %{"query" => query} = Jason.decode!(body) + + if String.contains?(query, "issue(id: $id)") do + Req.Test.json(conn, %{"data" => %{"issue" => issue_map()}}) + else + Req.Test.json(conn, issues_response([issue_map()])) + end + end) + + output = + capture_io(fn -> + assert :ok = LinearCli.CLI.main(["issue", "list", "--full", "CRY-1"]) + end) + + assert output =~ "[In Progress]" + assert output =~ "Fix the thing" + end + test "--all removes completedAt and canceledAt null-check filters" do test_pid = self() @@ -379,6 +423,62 @@ defmodule LinearCli.CLI.IssueCommandsTest do assert_received {:halted, 1} end + + test "compact listing includes workflow state name in brackets" do + Req.Test.stub(LinearCli.Api, fn conn -> + {:ok, body, conn} = Plug.Conn.read_body(conn) + %{"query" => query} = Jason.decode!(body) + + if String.contains?(query, "projects(") do + raise "issue list must not query projects when --project wasn't given" + end + + Req.Test.json( + conn, + issues_response([ + issue_map(%{"state" => %{"id" => "s2", "name" => "In Review", "type" => "started"}}) + ]) + ) + end) + + output = capture_io(fn -> assert :ok = LinearCli.CLI.main(["issue", "list"]) end) + assert output =~ "[In Review]" + assert output =~ "Fix the thing" + end + + test "compact listing omits state bracket when state is nil" do + Req.Test.stub(LinearCli.Api, fn conn -> + {:ok, body, conn} = Plug.Conn.read_body(conn) + %{"query" => _} = Jason.decode!(body) + Req.Test.json(conn, issues_response([issue_map(%{"state" => nil})])) + end) + + output = capture_io(fn -> assert :ok = LinearCli.CLI.main(["issue", "list"]) end) + assert output =~ "CRY-1" + refute output =~ "[" + end + + test "--full listing includes workflow state name in header" do + Req.Test.stub(LinearCli.Api, fn conn -> + {:ok, body, conn} = Plug.Conn.read_body(conn) + %{"query" => _} = Jason.decode!(body) + + Req.Test.json(conn, %{ + "data" => %{ + "issue" => + issue_map(%{"state" => %{"id" => "s3", "name" => "Done", "type" => "completed"}}) + } + }) + end) + + output = + capture_io(fn -> + assert :ok = LinearCli.CLI.main(["issue", "list", "--full", "CRY-1"]) + end) + + assert output =~ "[Done]" + assert output =~ "Fix the thing" + end end describe "issue create (Ruby: commands/issue/create.rb)" do diff --git a/app/test/linear_cli/cli/profile_defaults_test.exs b/app/test/linear_cli/cli/profile_defaults_test.exs index 67507da..3ede985 100644 --- a/app/test/linear_cli/cli/profile_defaults_test.exs +++ b/app/test/linear_cli/cli/profile_defaults_test.exs @@ -73,6 +73,7 @@ defmodule LinearCli.CLI.ProfileDefaultsTest do "branchName" => "cry-1-fix-the-thing", "description" => "It is broken", "assignee" => nil, + "state" => %{"id" => "s1", "name" => "In Progress", "type" => "started"}, "team" => team_map("ENG"), "comments" => %{"nodes" => []} }, From 92858c31872437adda5844ab30b62725d3e16071 Mon Sep 17 00:00:00 2001 From: "Tj (bougyman) Vanderpoel" Date: Thu, 20 Aug 2026 11:11:29 -0400 Subject: [PATCH 2/2] test(EXT-5): remove duplicate workflow state listing tests The three tests added at the bottom of the describe block (compact with state, compact nil-state, full with state) are equivalent to the three tests at lines 260-301. Keep only the lower set - it is slightly more thorough (includes a projects-query guard) and uses body in Jason.decode! so no unused-variable compiler warnings arise. Co-Authored-By: Claude Sonnet 4.6 --- .../linear_cli/cli/issue_commands_test.exs | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/app/test/linear_cli/cli/issue_commands_test.exs b/app/test/linear_cli/cli/issue_commands_test.exs index f9a3927..c41940e 100644 --- a/app/test/linear_cli/cli/issue_commands_test.exs +++ b/app/test/linear_cli/cli/issue_commands_test.exs @@ -257,49 +257,6 @@ defmodule LinearCli.CLI.IssueCommandsTest do assert output =~ "CRY-1" end - test "compact listing shows workflow status name in brackets" do - Req.Test.stub(LinearCli.Api, fn conn -> - {:ok, body, conn} = Plug.Conn.read_body(conn) - Req.Test.json(conn, issues_response([issue_map()])) - end) - - output = capture_io(fn -> assert :ok = LinearCli.CLI.main(["issue", "list"]) end) - assert output =~ "[In Progress]" - assert output =~ "Fix the thing" - end - - test "compact listing omits status brackets when state is absent" do - Req.Test.stub(LinearCli.Api, fn conn -> - {:ok, body, conn} = Plug.Conn.read_body(conn) - Req.Test.json(conn, issues_response([issue_map(%{"state" => nil})])) - end) - - output = capture_io(fn -> assert :ok = LinearCli.CLI.main(["issue", "list"]) end) - assert output =~ "CRY-1" - refute output =~ "[" - end - - test "--full listing shows workflow status in the header line" do - Req.Test.stub(LinearCli.Api, fn conn -> - {:ok, body, conn} = Plug.Conn.read_body(conn) - %{"query" => query} = Jason.decode!(body) - - if String.contains?(query, "issue(id: $id)") do - Req.Test.json(conn, %{"data" => %{"issue" => issue_map()}}) - else - Req.Test.json(conn, issues_response([issue_map()])) - end - end) - - output = - capture_io(fn -> - assert :ok = LinearCli.CLI.main(["issue", "list", "--full", "CRY-1"]) - end) - - assert output =~ "[In Progress]" - assert output =~ "Fix the thing" - end - test "--all removes completedAt and canceledAt null-check filters" do test_pid = self()