Files
dotfiles/pi/files/agent/skills/linear/linear-issues.js
T
2026-03-19 16:37:27 +00:00

91 lines
2.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
// List Linear issues with filters
// Usage: linear-issues.js [--team <key>] [--state <name>] [--assignee <name|me>] [--label <name>] [--project <name>] [-n <num>]
import { getClient, formatDate, truncate } from "./lib.js";
const args = process.argv.slice(2);
function extractArg(flag) {
const idx = args.indexOf(flag);
if (idx !== -1 && args[idx + 1]) {
const val = args[idx + 1];
args.splice(idx, 2);
return val;
}
return null;
}
const numResults = parseInt(extractArg("-n") || "25", 10);
const teamKey = extractArg("--team");
const stateName = extractArg("--state");
const assigneeName = extractArg("--assignee");
const labelName = extractArg("--label");
const projectName = extractArg("--project");
if (args.includes("--help") || args.includes("-h")) {
console.log("Usage: linear-issues.js [options]");
console.log("\nOptions:");
console.log(" --team <key> Filter by team key (e.g. ENG)");
console.log(" --state <name> Filter by state (e.g. 'In Progress', 'Todo')");
console.log(" --assignee <name> Filter by assignee name or 'me'");
console.log(" --label <name> Filter by label name");
console.log(" --project <name> Filter by project name");
console.log(" -n <num> Number of results (default: 25)");
process.exit(0);
}
const client = getClient();
// Build filter
const filter = {};
if (teamKey) {
filter.team = { key: { eq: teamKey.toUpperCase() } };
}
if (stateName) {
filter.state = { name: { eqIgnoreCase: stateName } };
}
if (assigneeName) {
if (assigneeName.toLowerCase() === "me") {
const me = await client.viewer;
filter.assignee = { id: { eq: me.id } };
} else {
filter.assignee = { name: { containsIgnoreCase: assigneeName } };
}
}
if (labelName) {
filter.labels = { name: { eqIgnoreCase: labelName } };
}
if (projectName) {
filter.project = { name: { containsIgnoreCase: projectName } };
}
const issues = await client.issues({
filter,
first: numResults,
orderBy: "updatedAt",
});
if (issues.nodes.length === 0) {
console.log("No issues found matching filters.");
process.exit(0);
}
for (const issue of issues.nodes) {
const state = await issue.state;
const team = await issue.team;
const assignee = await issue.assignee;
console.log(
`${issue.identifier.padEnd(12)} ${(state?.name || "?").padEnd(14)} ${(issue.priorityLabel || "").padEnd(8)} ${(assignee?.name || "Unassigned").padEnd(20)} ${truncate(issue.title, 80)}`
);
}
console.log(`\n${issues.nodes.length} issue(s) shown.`);