diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fb22eb..49a97cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- various issues with issue list: --team, --sort flags work now, workspace doesn't need to be set (useful when running unconfigured) + ### Changed - removed uneccessary double prompt around adding labels diff --git a/src/commands/issue/issue-list.ts b/src/commands/issue/issue-list.ts index 0b9259f..2a7ea74 100644 --- a/src/commands/issue/issue-list.ts +++ b/src/commands/issue/issue-list.ts @@ -83,7 +83,7 @@ export const listCommand = new Command() ) => { const usePager = pager !== false if (web || app) { - await openTeamAssigneeView({ app: app }) + await openTeamAssigneeView({ app: app, team }) return } @@ -110,8 +110,10 @@ export const listCommand = new Command() Deno.exit(1) } - const sort = sortFlag || - getOption("issue_sort") as "manual" | "priority" | undefined + const sort = getOption("issue_sort", sortFlag) as + | "manual" + | "priority" + | undefined if (!sort) { console.error( "Sort must be provided via command line flag, configuration file, or LINEAR_ISSUE_SORT environment variable", @@ -142,6 +144,7 @@ export const listCommand = new Command() assignee, unassigned, allAssignees, + sort, ) spinner?.stop() const issues = result.issues?.nodes || [] diff --git a/src/utils/actions.ts b/src/utils/actions.ts index 13c3ec1..c43374b 100644 --- a/src/utils/actions.ts +++ b/src/utils/actions.ts @@ -55,8 +55,10 @@ export async function openProjectPage( await open(url, options.app ? { app: { name: "Linear" } } : undefined) } -export async function openTeamAssigneeView(options: { app?: boolean } = {}) { - const teamId = getTeamKey() +export async function openTeamAssigneeView( + options: { app?: boolean; team?: string } = {}, +) { + const teamId = options.team || getTeamKey() if (!teamId) { console.error( "Could not determine team id from configuration or directory name.", @@ -64,12 +66,23 @@ export async function openTeamAssigneeView(options: { app?: boolean } = {}) { Deno.exit(1) } - const workspace = getOption("workspace") + let workspace = getOption("workspace") if (!workspace) { - console.error( - "workspace is not set via command line, configuration file, or environment.", - ) - Deno.exit(1) + // Get workspace from viewer if not configured + const { gql } = await import("../__codegen__/gql.ts") + const { getGraphQLClient } = await import("./graphql.ts") + const client = getGraphQLClient() + const viewerQuery = gql(` + query GetViewer { + viewer { + organization { + urlKey + } + } + } + `) + const result = await client.request(viewerQuery) + workspace = result.viewer.organization.urlKey } const filterObj = { diff --git a/src/utils/linear.ts b/src/utils/linear.ts index 1bd4ad4..9ebb048 100644 --- a/src/utils/linear.ts +++ b/src/utils/linear.ts @@ -304,9 +304,11 @@ export async function fetchIssuesForState( assignee?: string, unassigned = false, allAssignees = false, + sort?: "manual" | "priority", ) { - const sort = getOption("issue_sort") as "manual" | "priority" | undefined - if (!sort) { + const sortValue = sort || + getOption("issue_sort") as "manual" | "priority" | undefined + if (!sortValue) { console.error( "Sort must be provided via configuration file or LINEAR_ISSUE_SORT environment variable", ) @@ -369,7 +371,7 @@ export async function fetchIssuesForState( `) let sortPayload: Array - switch (sort) { + switch (sortValue) { case "manual": sortPayload = [ { workflowState: { order: "Descending" } }, @@ -383,7 +385,7 @@ export async function fetchIssuesForState( ] break default: - throw new Error(`Unknown sort type: ${sort}`) + throw new Error(`Unknown sort type: ${sortValue}`) } const client = getGraphQLClient() diff --git a/test/commands/issue/__snapshots__/issue-view.test.ts.snap b/test/commands/issue/__snapshots__/issue-view.test.ts.snap index 8808edb..69b6fbb 100644 --- a/test/commands/issue/__snapshots__/issue-view.test.ts.snap +++ b/test/commands/issue/__snapshots__/issue-view.test.ts.snap @@ -24,8 +24,8 @@ stderr: snapshot[`Issue View Command - With Issue ID 1`] = ` stdout: -"Error: error sending request for url (http://127.0.0.1:3000/graphql): client error (Connect): tcp connect error: Connection refused: Connection refused -" +'Error: GraphQL Error (Code: 401): {"response":{"status":401,"headers":{}},"request":{"query":"query GetIssueDetailsWithComments(\$id: String!) {\\\\n issue(id: \$id) {\\\\n title\\\\n description\\\\n url\\\\n branchName\\\\n comments(first: 50, orderBy: createdAt) {\\\\n nodes {\\\\n id\\\\n body\\\\n createdAt\\\\n user {\\\\n name\\\\n displayName\\\\n }\\\\n externalUser {\\\\n name\\\\n displayName\\\\n }\\\\n parent {\\\\n id\\\\n }\\\\n }\\\\n }\\\\n }\\\\n}","variables":{"id":"TEST-123"}}} +' stderr: "✗ Failed to fetch issue details " diff --git a/test/commands/issue/issue-list.test.ts b/test/commands/issue/issue-list.test.ts index 277bae4..7ed6b98 100644 --- a/test/commands/issue/issue-list.test.ts +++ b/test/commands/issue/issue-list.test.ts @@ -1,4 +1,5 @@ import { snapshotTest } from "@cliffy/testing" +import { assertEquals } from "@std/assert" import { listCommand } from "../../../src/commands/issue/issue-list.ts" import { commonDenoArgs } from "../../utils/test-helpers.ts" @@ -13,3 +14,21 @@ await snapshotTest({ await listCommand.parse() }, }) + +Deno.test("Issue List Command - sort flag should work", async () => { + const args = ["--team", "pre", "-A", "--sort", "priority"] + + // This should not throw an error about sort being required + try { + await listCommand.parse(args) + } catch (error) { + // We expect it to fail for other reasons (like API calls), but not for sort validation + if (error instanceof Error) { + assertEquals( + error.message.includes("Sort must be provided"), + false, + "Sort flag was provided but validation still failed", + ) + } + } +}) diff --git a/test/commands/issue/issue-view.test.ts b/test/commands/issue/issue-view.test.ts index 1fc3161..1b83567 100644 --- a/test/commands/issue/issue-view.test.ts +++ b/test/commands/issue/issue-view.test.ts @@ -45,10 +45,9 @@ await snapshotTest({ // Expected to fail with mock endpoint, capture the error for snapshot // Normalize error message to be consistent across platforms const message = (error as Error).message - const normalizedMessage = message.replace( - /Connection refused \(os error \d+\)/g, - "Connection refused", - ) + const normalizedMessage = message + .replace(/Connection refused \(os error \d+\)/g, "Connection refused") + .replace(/: Connection refused$/g, "") console.log(`Error: ${normalizedMessage}`) } finally { // Clean up environment