Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ linear issue list --all-assignees
other options:

```bash
# List issues for specific team
# List issues for specific team (auto-detected if you belong to one team)
linear issue list --team TEAM

# Sort by priority instead of manual order
linear issue list --sort priority
# Sort by manual order instead of default priority order
linear issue list --sort manual

# Open in web browser
linear issue list --web
Expand Down Expand Up @@ -289,8 +289,8 @@ linear issue view
# Create and start a new bug fix
linear issue create --title "Fix login error" --label bug --start

# List high priority issues
linear issue list --sort priority
# List issues in manual sort order
linear issue list --sort manual

# Create a pull request for current issue
linear issue pr
Expand Down
44 changes: 34 additions & 10 deletions src/commands/issue/issue-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
getProjectOptionsByName,
getTeamIdByKey,
getTeamKey,
getViewerTeams,
selectOption,
} from "../../utils/linear.ts"
import { openTeamAssigneeView } from "../../utils/actions.ts"
Expand Down Expand Up @@ -145,22 +146,45 @@ export const listCommand = new Command()
}

const sort = sortFlag ||
getOption("issue_sort") as "manual" | "priority" | undefined
if (!sort) {
throw new ValidationError(
"Sort must be provided via command line flag, configuration file, or LINEAR_ISSUE_SORT environment variable",
)
}
getOption("issue_sort") as "manual" | "priority" | undefined ||
"priority"
if (!SortType.values().includes(sort)) {
throw new ValidationError(
`Sort must be one of: ${SortType.values().join(", ")}`,
)
}
const teamKey = team || getTeamKey()
let teamKey = team || getTeamKey()
if (!teamKey) {
throw new ValidationError(
"Could not determine team key from directory name or team flag",
)
const viewerTeams = await getViewerTeams()
if (viewerTeams.length === 0) {
throw new ValidationError(
"No teams found for the authenticated user",
{
suggestion:
"Join a team in Linear, or specify one with --team.",
},
)
} else if (viewerTeams.length === 1) {
teamKey = viewerTeams[0].key
} else if (Deno.stdin.isTerminal()) {
const { Select } = await import("@cliffy/prompt")
teamKey = await Select.prompt({
message: "Select a team",
options: viewerTeams.map((t) => ({
name: `${t.name} (${t.key})`,
value: t.key,
})),
})
} else {
const teamList = viewerTeams.map((t) => `${t.name} (${t.key})`)
.join(", ")
throw new ValidationError(
"Multiple teams found; specify one with --team",
{
suggestion: `Available teams: ${teamList}`,
},
)
}
}

let projectId: string | undefined
Expand Down
40 changes: 30 additions & 10 deletions src/utils/linear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,16 +424,8 @@ export async function fetchIssuesForState(
milestoneId?: string,
) {
const sort = sortParam ??
getOption("issue_sort") as "manual" | "priority" | undefined
if (!sort) {
throw new ValidationError(
"Sort must be provided",
{
suggestion:
"Use --sort parameter, set in configuration file, or set LINEAR_ISSUE_SORT environment variable",
},
)
}
getOption("issue_sort") as "manual" | "priority" | undefined ??
"priority"

const filter: IssueFilter = {
team: { key: { eq: teamKey } },
Expand Down Expand Up @@ -807,6 +799,34 @@ export async function getIssueLabelOptionsByNameForTeam(
return Object.fromEntries(sortedResults.map((t) => [t.id, t.name]))
}

/**
* Fetch the teams the authenticated user belongs to via the viewer query.
* Returns teams sorted alphabetically by name.
*/
export async function getViewerTeams(): Promise<
Array<{ key: string; name: string }>
> {
const client = getGraphQLClient()
const query = gql(/* GraphQL */ `
query GetViewerTeams {
viewer {
teams {
nodes {
key
name
}
}
}
}
`)

const data = await client.request(query, {})
const teams = data.viewer.teams.nodes
return teams.sort((a: { name: string }, b: { name: string }) =>
a.name.toLowerCase().localeCompare(b.name.toLowerCase())
)
}

export async function getAllTeams(): Promise<
Array<{ id: string; key: string; name: string }>
> {
Expand Down
Loading