import { tool } from "@opencode-ai/plugin"; import { $ } from "bun"; export const issueDepsList = tool({ description: "List dependency relationships for an issue", args: { issueNumber: tool.schema.number().describe("Issue number"), }, async execute(args) { try { const result = await $`tea issue ${args.issueNumber} --output json --comments`.text(); const issue = JSON.parse(result); const dependencies: { issueNumber: number; title: string; blocks: Array<{ issueNumber: number; relationship: "blocks" }>; blockedBy: Array<{ issueNumber: number; relationship: "blockedBy" }>; } = { issueNumber: issue.index, title: issue.title, blocks: [], blockedBy: [], }; for (const comment of issue.comments ?? []) { const text = comment.body ?? ""; const matches = text.matchAll(/\b(blocks|blocked by)\s+#(\d+)/gi); for (const match of matches) { const relationshipText = match[1].toLowerCase(); const relatedIssueNum = Number(match[2]); if (relationshipText === "blocks") { dependencies.blocks.push({ issueNumber: relatedIssueNum, relationship: "blocks", }); } else { dependencies.blockedBy.push({ issueNumber: relatedIssueNum, relationship: "blockedBy", }); } } } return dependencies; } catch (error: any) { return { error: "Failed to get issue dependencies", message: error.message, stderr: error.stderr?.toString(), }; } }, }); export const issueDepsAdd = tool({ description: "Add a dependency relationship between issues", args: { issueNumber: tool.schema.number().describe("Primary issue number"), relatedIssueNumber: tool.schema.number().describe("Related issue number"), relationship: tool.schema .enum(["blocks", "blockedBy"]) .describe("'blocks' means issueNumber blocks relatedIssueNumber"), comment: tool.schema.string().optional().describe("Optional comment"), }, async execute(args) { try { let commentText = args.relationship === "blocks" ? `blocks #${args.relatedIssueNumber}` : `blocked by #${args.relatedIssueNumber}`; if (args.comment) { commentText += `\n\n${args.comment}`; } const result = await $`tea issue comment --output json --issue ${args.issueNumber} --body ${commentText}`.text(); return JSON.parse(result); } catch (error: any) { return { error: "Failed to add issue dependency", message: error.message, stderr: error.stderr?.toString(), }; } }, }); export const issueDepsRemove = tool({ description: "Remove a dependency relationship between issues by commenting on the issue", args: { issueNumber: tool.schema.number().describe("Primary issue number"), relatedIssueNumber: tool.schema.number().describe("Related issue number"), }, async execute(args) { try { const commentText = `removing dependency relationship with #${args.relatedIssueNumber}`; const result = await $`tea issue comment --output json --issue ${args.issueNumber} --body ${commentText}`.text(); return JSON.parse(result); } catch (error: any) { return { error: "Failed to remove issue dependency", message: error.message, stderr: error.stderr?.toString(), }; } }, });