import { tool } from "@opencode-ai/plugin"; import { $ } from "bun"; export const issueList = tool({ description: "List issues with filters for state, labels, assignee, milestone, and author", args: { state: tool.schema .enum(["open", "closed", "all"]) .default("open") .describe("Filter by state"), labels: tool.schema .string() .optional() .describe("Comma-separated list of labels to match"), assignee: tool.schema .string() .optional() .describe("Filter by assignee username"), milestone: tool.schema .string() .optional() .describe("Filter by milestone name"), author: tool.schema .string() .optional() .describe("Filter by author username"), limit: tool.schema .number() .default(30) .describe("Number of issues to return"), keyword: tool.schema .string() .optional() .describe("Search keyword in title and body"), }, async execute(args, context) { try { let cmd = $`tea issue list --output json --state ${args.state} --limit ${args.limit ?? 30}`; if (args.labels && args.labels.length > 0) { cmd = cmd`--labels ${args.labels}`; } if (args.assignee && args.assignee.length > 0) { cmd = cmd`--assignee ${args.assignee}`; } if (args.milestone && args.milestone.length > 0) { cmd = cmd`--milestones ${args.milestone}`; } if (args.author && args.author.length > 0) { cmd = cmd`--author ${args.author}`; } if (args.keyword && args.keyword.length > 0) { cmd = cmd`--keyword ${args.keyword}`; } return await cmd.text(); } catch (error: any) { return { error: "Failed to list issues", message: error.message, stderr: error.stderr?.toString(), }; } }, }); export const issueCreate = tool({ description: "Create a new issue with title, body, labels, milestone, and assignees", args: { title: tool.schema.string().describe("Issue title"), body: tool.schema.string().optional().describe("Issue description/body"), labels: tool.schema .array(tool.schema.string()) .optional() .describe("Comma-separated list of label names"), milestone: tool.schema.string().optional().describe("Milestone name"), assignees: tool.schema .array(tool.schema.string()) .optional() .describe("Comma-separated list of assignee usernames"), }, async execute(args, context) { try { let cmd = $`tea issue create --output json --title ${args.title}`; if (args.body) { cmd = cmd`--body ${args.body}`; } if (args.labels) { cmd = cmd`--labels ${args.labels.join(",")}`; } if (args.milestone) { cmd = cmd`--milestone ${args.milestone}`; } if (args.assignees) { cmd = cmd`--assignee ${args.assignees.join(",")}`; } return await cmd.text(); } catch (error: any) { return { error: "Failed to create issue", message: error.message, stderr: error.stderr?.toString(), }; } }, }); export const issueEdit = tool({ description: "Update an existing issue with partial updates to title, body, labels, milestone, or assignees", args: { issueNumber: tool.schema.number().describe("Issue number"), title: tool.schema.string().optional().describe("New title"), body: tool.schema.string().optional().describe("New description/body"), labels: tool.schema .array(tool.schema.string()) .optional() .describe("New comma-separated list of label names"), milestone: tool.schema.string().optional().describe("New milestone name"), assignees: tool.schema .array(tool.schema.string()) .optional() .describe("New comma-separated list of assignee usernames"), state: tool.schema .enum(["open", "closed"]) .optional() .describe("New state"), }, async execute(args, context) { try { let cmd = $`tea issue edit --output json ${args.issueNumber}`; if (args.title) { cmd = cmd`--title ${args.title}`; } if (args.body) { cmd = cmd`--body ${args.body}`; } if (args.labels) { cmd = cmd`--labels ${args.labels.join(",")}`; } if (args.milestone) { cmd = cmd`--milestone ${args.milestone}`; } if (args.assignees) { cmd = cmd`--assignee ${args.assignees.join(",")}`; } if (args.state) { cmd = cmd`--state ${args.state}`; } return await cmd.text(); } catch (error: any) { return { error: "Failed to edit issue", message: error.message, stderr: error.stderr?.toString(), }; } }, }); export const issueDetails = tool({ description: "Get detailed information about a specific issue including dependencies and comments", args: { issueNumber: tool.schema.number().describe("Issue number"), }, async execute(args, context) { try { return await $`tea issue ${args.issueNumber} --output json --comments`.text(); } catch (error: any) { return { error: "Failed to get issue details", message: error.message, stderr: error.stderr?.toString(), }; } }, });