feat: add tea-pr.ts tool for PR management (prList, prCreate, prCheckout, prMerge, prDetails)

This commit is contained in:
2026-05-03 16:34:18 +02:00
parent cdfacbac18
commit f9a72c3543

137
.opencode/tools/tea-pr.ts Normal file
View File

@@ -0,0 +1,137 @@
import { tool } from "@opencode-ai/plugin"
import { $ } from "bun"
export const prList = tool({
description: "List pull requests with their current state, useful for tracking work in progress or finding PRs to review",
args: {
state: tool.schema.enum(["open", "closed", "all"]).default("open").describe("Filter by state"),
author: tool.schema.string().optional().describe("Filter by author username"),
limit: tool.schema.number().default(30).describe("Number of PRs to return"),
},
async execute(args, context) {
try {
const cmd = args.author
? $`tea pr list --output json --state ${args.state} --author ${args.author} --limit ${args.limit}`
: $`tea pr list --output json --state ${args.state} --limit ${args.limit}`
const result = await cmd.text()
return JSON.parse(result)
} catch (error: any) {
return {
error: "Failed to list pull requests",
message: error.message,
stderr: error.stderr?.toString(),
}
}
},
})
export const prCreate = tool({
description: "Create a new pull request with title, body, base branch, head branch, and optional labels and milestone",
args: {
title: tool.schema.string().describe("PR title"),
body: tool.schema.string().optional().describe("PR description/body"),
base: tool.schema.string().describe("Base branch name"),
head: tool.schema.string().describe("Head branch name"),
labels: tool.schema.array(tool.schema.string()).optional().describe("Comma-separated list of label names"),
milestone: tool.schema.string().optional().describe("Milestone name"),
},
async execute(args, context) {
try {
let cmd = $`tea pr create --output json --title ${args.title} --base ${args.base} --head ${args.head}`
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}`
}
const result = await cmd.text()
return JSON.parse(result)
} catch (error: any) {
return {
error: "Failed to create pull request",
message: error.message,
stderr: error.stderr?.toString(),
}
}
},
})
export const prCheckout = tool({
description: "Checkout a pull request locally to work on it",
args: {
prNumber: tool.schema.number().describe("Pull request number"),
},
async execute(args, context) {
try {
const result = await $`tea pr checkout ${args.prNumber}`.text()
return {
success: true,
message: result,
}
} catch (error: any) {
return {
error: "Failed to checkout pull request",
message: error.message,
stderr: error.stderr?.toString(),
}
}
},
})
export const prMerge = tool({
description: "Merge a pull request using rebase merge style",
args: {
prNumber: tool.schema.number().describe("Pull request number"),
title: tool.schema.string().optional().describe("Merge commit title"),
message: tool.schema.string().optional().describe("Merge commit message"),
},
async execute(args, context) {
try {
let cmd = $`tea pr merge --style rebase --output json ${args.prNumber}`
if (args.title) {
cmd = cmd`--title ${args.title}`
}
if (args.message) {
cmd = cmd`--message ${args.message}`
}
const result = await cmd.text()
return JSON.parse(result)
} catch (error: any) {
return {
error: "Failed to merge pull request",
message: error.message,
stderr: error.stderr?.toString(),
}
}
},
})
export const prDetails = tool({
description: "Get detailed information about a specific pull request including review status and comments",
args: {
prNumber: tool.schema.number().describe("Pull request number"),
},
async execute(args, context) {
try {
const result = await $`tea pr ${args.prNumber} --output json --comments`.text()
return JSON.parse(result)
} catch (error: any) {
return {
error: "Failed to get pull request details",
message: error.message,
stderr: error.stderr?.toString(),
}
}
},
})