import { tool } from "@opencode-ai/plugin" import { $ } from "bun" export const issueDepsList = tool({ description: "List dependency relationships for an issue (what it blocks and what blocks it)", args: { issueNumber: tool.schema.number().describe("Issue number"), }, async execute(args, context) { try { const result = await $`tea issue ${args.issueNumber} --output json --comments`.text() const issue = JSON.parse(result) const dependencies = { issueNumber: issue.index, title: issue.title, blocks: [], blockedBy: [], } if (issue.comments && Array.isArray(issue.comments)) { for (const comment of issue.comments) { const text = comment.body || "" const depMatch = text.match(/blocks\s+#[0-9]+|blocked by\s+#[0-9]+/i) if (depMatch) { const relatedIssueMatch = text.match(/#[0-9]+/) if (relatedIssueMatch) { const relatedIssueNum = parseInt(relatedIssueMatch[0], 10) const isBlocks = depMatch[0].toLowerCase().startsWith("blocks") if (isBlocks) { 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 (issue A blocks issue B, or issue A is blocked by issue B)", args: { issueNumber: tool.schema.number().describe("Primary issue number"), relatedIssueNumber: tool.schema.number().describe("Related issue number"), relationship: tool.schema.enum(["blocks", "blockedBy"]).describe("Relationship type: 'blocks' means issueNumber blocks relatedIssueNumber, 'blockedBy' means issueNumber is blocked by relatedIssueNumber"), comment: tool.schema.string().optional().describe("Optional comment to add with the dependency"), }, async execute(args, context) { try { let commentText = "" if (args.relationship === "blocks") { commentText = `@${args.relatedIssueNumber} blocks #${args.issueNumber}` } else { commentText = `@${args.issueNumber} is 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 to remove dependency from"), }, async execute(args, context) { try { const commentText = `@${args.relatedIssueNumber} removing dependency relationship` 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(), } } }, })