120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
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(),
|
|
};
|
|
}
|
|
},
|
|
});
|