diff --git a/.opencode/tools/tea-issue-deps.ts b/.opencode/tools/tea-issue-deps.ts index efc8e10..67ad115 100644 --- a/.opencode/tools/tea-issue-deps.ts +++ b/.opencode/tools/tea-issue-deps.ts @@ -1,286 +1,119 @@ -import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" +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)", + description: "List dependency relationships for an issue", args: { issueNumber: tool.schema.number().describe("Issue number"), }, - async execute(args, context) { + async execute(args) { try { - const result = await $`tea issue ${args.issueNumber} --output json --comments`.text() - const issue = JSON.parse(result) - - const dependencies = { + 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: [], - } - - 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", - }) - } - } + }; + + 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 + + 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)", + 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("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"), + relationship: tool.schema + .enum(["blocks", "blockedBy"]) + .describe("'blocks' means issueNumber blocks relatedIssueNumber"), + comment: tool.schema.string().optional().describe("Optional comment"), }, - async execute(args, context) { + async execute(args) { 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 import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" + let commentText = + args.relationship === "blocks" + ? `blocks #${args.relatedIssueNumber}` + : `blocked by #${args.relatedIssueNumber}`; -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}` + commentText += `\n\n${args.comment}`; } - - tea issue comment --output json --issue ${args.issueNumber} --body ${commentText}`.text() - return result + + 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 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)", + 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"), - 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) { + async execute(args) { 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(), - } - } - }, -}) + const commentText = `removing dependency relationship with #${args.relatedIssueNumber}`; -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` - - tea issue comment --output json --issue ${args.issueNumber} --body ${commentText}`.text() - return result + 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(), - } + }; } }, -}) \ No newline at end of file +});