linear skill
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Create a new Linear issue
|
||||
// Usage: linear-create.js --team <key> --title <title> [--description <desc>] [--state <name>] [--priority <0-4>] [--assignee <name|me>] [--label <name>] [--parent <identifier>]
|
||||
|
||||
import { getClient } 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 teamKey = extractArg("--team");
|
||||
const title = extractArg("--title");
|
||||
const description = extractArg("--description");
|
||||
const stateName = extractArg("--state");
|
||||
const priority = extractArg("--priority");
|
||||
const assigneeName = extractArg("--assignee");
|
||||
const labelName = extractArg("--label");
|
||||
const parentId = extractArg("--parent");
|
||||
|
||||
if (!teamKey || !title) {
|
||||
console.log("Usage: linear-create.js --team <key> --title <title> [options]");
|
||||
console.log("\nRequired:");
|
||||
console.log(" --team <key> Team key (e.g. ENG)");
|
||||
console.log(' --title <title> Issue title');
|
||||
console.log("\nOptional:");
|
||||
console.log(" --description <text> Issue description (markdown)");
|
||||
console.log(" --state <name> Initial state (e.g. 'Todo')");
|
||||
console.log(" --priority <0-4> Priority: 0=None, 1=Urgent, 2=High, 3=Medium, 4=Low");
|
||||
console.log(" --assignee <name|me> Assignee name or 'me'");
|
||||
console.log(" --label <name> Label name");
|
||||
console.log(" --parent <id> Parent issue identifier (e.g. ATT-100)");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const client = getClient();
|
||||
|
||||
// Resolve team
|
||||
const teams = await client.teams({ filter: { key: { eq: teamKey.toUpperCase() } } });
|
||||
const team = teams.nodes[0];
|
||||
if (!team) {
|
||||
console.error(`Team '${teamKey}' not found.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const input = {
|
||||
teamId: team.id,
|
||||
title,
|
||||
};
|
||||
|
||||
if (description) input.description = description;
|
||||
if (priority) input.priority = parseInt(priority, 10);
|
||||
|
||||
// Resolve state
|
||||
if (stateName) {
|
||||
const states = await team.states();
|
||||
const state = states.nodes.find(
|
||||
(s) => s.name.toLowerCase() === stateName.toLowerCase()
|
||||
);
|
||||
if (state) input.stateId = state.id;
|
||||
else console.warn(`Warning: State '${stateName}' not found, using default.`);
|
||||
}
|
||||
|
||||
// Resolve assignee
|
||||
if (assigneeName) {
|
||||
if (assigneeName.toLowerCase() === "me") {
|
||||
const me = await client.viewer;
|
||||
input.assigneeId = me.id;
|
||||
} else {
|
||||
const users = await client.users({ filter: { name: { containsIgnoreCase: assigneeName } } });
|
||||
if (users.nodes[0]) input.assigneeId = users.nodes[0].id;
|
||||
else console.warn(`Warning: User '${assigneeName}' not found.`);
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve label
|
||||
if (labelName) {
|
||||
const labels = await client.issueLabels({ filter: { name: { eqIgnoreCase: labelName } } });
|
||||
if (labels.nodes[0]) input.labelIds = [labels.nodes[0].id];
|
||||
else console.warn(`Warning: Label '${labelName}' not found.`);
|
||||
}
|
||||
|
||||
// Resolve parent
|
||||
if (parentId) {
|
||||
const parentSearch = await client.searchIssues(parentId, { first: 1 });
|
||||
if (parentSearch.nodes[0]) input.parentId = parentSearch.nodes[0].id;
|
||||
else console.warn(`Warning: Parent '${parentId}' not found.`);
|
||||
}
|
||||
|
||||
const result = await client.createIssue(input);
|
||||
const issue = await result.issue;
|
||||
|
||||
console.log(`Created: ${issue.identifier} - ${issue.title}`);
|
||||
console.log(`URL: ${issue.url}`);
|
||||
Reference in New Issue
Block a user