From 09c9527e93ca60befd876767175a563935e90ab0 Mon Sep 17 00:00:00 2001 From: Hugo Nijhuis Date: Thu, 14 May 2026 23:08:40 +0200 Subject: [PATCH] cleanup --- .opencode/tools/git-worktree.ts | 241 ------------------------ .opencode/tools/tea-context.ts | 19 -- .opencode/tools/tea-issue-close.ts | 82 -------- .opencode/tools/tea-issue-deps.ts | 119 ------------ .opencode/tools/tea-issue-update.ts | 155 --------------- .opencode/tools/tea-issue.ts | 196 ------------------- .opencode/tools/tea-label-update.ts | 100 ---------- .opencode/tools/tea-label.ts | 19 -- .opencode/tools/tea-milestone-update.ts | 99 ---------- .opencode/tools/tea-milestone.ts | 52 ----- .opencode/tools/tea-notification.ts | 21 --- .opencode/tools/tea-pr-review.ts | 110 ----------- .opencode/tools/tea-pr.ts | 145 -------------- 13 files changed, 1358 deletions(-) delete mode 100644 .opencode/tools/git-worktree.ts delete mode 100644 .opencode/tools/tea-context.ts delete mode 100644 .opencode/tools/tea-issue-close.ts delete mode 100644 .opencode/tools/tea-issue-deps.ts delete mode 100644 .opencode/tools/tea-issue-update.ts delete mode 100644 .opencode/tools/tea-issue.ts delete mode 100644 .opencode/tools/tea-label-update.ts delete mode 100644 .opencode/tools/tea-label.ts delete mode 100644 .opencode/tools/tea-milestone-update.ts delete mode 100644 .opencode/tools/tea-milestone.ts delete mode 100644 .opencode/tools/tea-notification.ts delete mode 100644 .opencode/tools/tea-pr-review.ts delete mode 100644 .opencode/tools/tea-pr.ts diff --git a/.opencode/tools/git-worktree.ts b/.opencode/tools/git-worktree.ts deleted file mode 100644 index 1491e41..0000000 --- a/.opencode/tools/git-worktree.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" -import { join, dirname } from "node:path" - -async function getWorktreeLocation() { - const repoRoot = await $`git rev-parse --show-toplevel`.text() - const worktreesDir = join(dirname(repoRoot), "worktrees") - return { repoRoot, worktreesDir } -} - -export const worktreeCreate = tool({ - description: "Create a new git worktree with specified name and branch", - args: { - name: tool.schema.string().describe("Worktree directory name (e.g., 'issue-42')"), - branch: tool.schema.string().describe("Git branch to attach (must exist or will be created from base)"), - base: tool.schema.string().optional().describe("Base branch for new branches (default: origin/main)"), - }, - async execute(args, context) { - try { - const { worktreesDir } = await getWorktreeLocation() - const worktreePath = join(worktreesDir, args.name) - - await $`mkdir -p ${worktreesDir}`.nothrow() - - const existingBranch = await $`git branch --list ${args.branch}`.text() - const base = args.base || "origin/main" - - if (existingBranch.trim()) { - await $`git worktree add ${worktreePath} ${args.branch}` - } else { - await $`git worktree add ${worktreePath} -b ${args.branch} ${base}` - } - - return { - success: true, - path: worktreePath, - } - } catch (error: any) { - return { - success: false, - error: "Failed to create worktree", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) - -export const worktreeList = tool({ - description: "List all worktrees with their paths and branches", - args: { - path: tool.schema.string().optional().describe("Specific worktree path to list (lists all if omitted)"), - }, - async execute(args, context) { - try { - const { repoRoot } = await getWorktreeLocation() - - let cmd - if (args.path) { - cmd = $`git worktree list --porcelain` - } else { - cmd = $`git worktree list --porcelain` - } - - const output = await cmd.text() - - const worktrees = output - .split("\n") - .filter((line) => line.startsWith("worktree ")) - .map((line) => { - const path = line.replace("worktree ", "").trim() - return { path } - }) - - return { - success: true, - worktrees, - } - } catch (error: any) { - return { - success: false, - error: "Failed to list worktrees", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) - -export const worktreeCheckout = tool({ - description: "Checkout an existing worktree by name", - args: { - name: tool.schema.string().describe("Worktree name to checkout"), - }, - async execute(args, context) { - try { - const { worktreesDir } = await getWorktreeLocation() - const worktreePath = join(worktreesDir, args.name) - - if (!(await $`test -d ${worktreePath}`.nothrow().text())) { - return { - success: false, - error: "Worktree does not exist", - message: `Worktree '${args.name}' not found at ${worktreePath}`, - } - } - - return { - success: true, - path: worktreePath, - } - } catch (error: any) { - return { - success: false, - error: "Failed to checkout worktree", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) - -export const worktreeRemove = tool({ - description: "Remove a worktree with dirty-check safety", - args: { - name: tool.schema.string().describe("Worktree name to remove"), - force: tool.schema.boolean().optional().describe("Force remove even if dirty"), - }, - async execute(args, context) { - try { - const { worktreesDir } = await getWorktreeLocation() - const worktreePath = join(worktreesDir, args.name) - - if (!(await $`test -d ${worktreePath}`.nothrow().text())) { - return { - success: false, - error: "Worktree does not exist", - message: `Worktree '${args.name}' not found at ${worktreePath}`, - } - } - - if (!args.force) { - const status = await $`git -C ${worktreePath} status --porcelain`.nothrow().text() - if (status.trim()) { - return { - success: false, - error: "Worktree has uncommitted changes", - message: "Use --force to remove anyway", - } - } - } - - await $`git worktree remove ${worktreePath} ${args.force ? "--force" : ""}` - - return { - success: true, - message: `Worktree '${args.name}' removed`, - } - } catch (error: any) { - return { - success: false, - error: "Failed to remove worktree", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) - -export const worktreeCleanup = tool({ - description: "Remove stale worktrees (manually invoked)", - args: { - olderThan: tool.schema.number().optional().describe("Remove worktrees older than N days (default: 7)"), - force: tool.schema.boolean().optional().describe("Force cleanup without confirmation"), - }, - async execute(args, context) { - try { - const { worktreesDir } = await getWorktreeLocation() - const olderThan = args.olderThan || 7 - - const output = await $`git worktree list --porcelain`.text() - - const worktrees = output - .split("\n") - .filter((line) => line.startsWith("worktree ")) - .map((line) => { - const path = line.replace("worktree ", "").trim() - return path - }) - - const now = new Date() - const staleWorktrees = [] - - for (const path of worktrees) { - if (!(await $`test -d ${path}`.nothrow().text())) { - continue - } - - const stat = await $`stat -f %m ${path}`.nothrow().text() - const mtime = parseInt(stat.trim()) * 1000 - const ageDays = (now.getTime() - mtime) / (1000 * 60 * 60 * 24) - - if (ageDays > olderThan) { - staleWorktrees.push({ path, age: Math.round(ageDays) }) - } - } - - if (staleWorktrees.length === 0) { - return { - success: true, - message: "No stale worktrees found", - } - } - - if (!args.force) { - return { - success: true, - staleWorktrees, - message: `Found ${staleWorktrees.length} stale worktree(s). Use --force to remove.`, - } - } - - for (const { path } of staleWorktrees) { - await $`git worktree remove ${path} --force`.nothrow() - } - - return { - success: true, - removed: staleWorktrees, - message: `Removed ${staleWorktrees.length} stale worktree(s)`, - } - } catch (error: any) { - return { - success: false, - error: "Failed to cleanup worktrees", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) diff --git a/.opencode/tools/tea-context.ts b/.opencode/tools/tea-context.ts deleted file mode 100644 index d6c0b1e..0000000 --- a/.opencode/tools/tea-context.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" - -export const whoami = tool({ - description: "Get current logged-in user info for the Gitea instance", - args: {}, - async execute(args, context) { - try { - const result = await $`tea whoami --output json`.text() - return result - } catch (error: any) { - return { - error: "Failed to get current user info", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) \ No newline at end of file diff --git a/.opencode/tools/tea-issue-close.ts b/.opencode/tools/tea-issue-close.ts deleted file mode 100644 index c17a6be..0000000 --- a/.opencode/tools/tea-issue-close.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { tool } from "@opencode-ai/plugin"; -import { $ } from "bun"; - -export const issueClose = tool({ - description: "Close one or more issues", - args: { - issueNumbers: tool.schema - .array(tool.schema.number()) - .describe("Issue number(s) to close"), - comment: tool.schema - .string() - .optional() - .describe("Optional comment explaining why the issue is being closed"), - }, - async execute(args) { - try { - const issueListStr = args.issueNumbers.join(" "); - - let cmd = $`tea issues close --output json ${issueListStr}`; - - if (args.comment) { - cmd = cmd`--comment ${args.comment}`; - } - - const result = await cmd.text(); - - return { - success: true, - message: `Successfully closed issue(s) #${args.issueNumbers.join(", ")}`, - issues: args.issueNumbers, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to close issue(s)", - message: error.message, - stderr: error.stderr?.toString(), - issues: args.issueNumbers, - }; - } - }, -}); - -export const issueReopen = tool({ - description: "Reopen one or more closed issues", - args: { - issueNumbers: tool.schema - .array(tool.schema.number()) - .describe("Issue number(s) to reopen"), - comment: tool.schema - .string() - .optional() - .describe("Optional comment explaining why the issue is being reopened"), - }, - async execute(args) { - try { - const issueListStr = args.issueNumbers.join(" "); - - let cmd = $`tea issues reopen --output json ${issueListStr}`; - - if (args.comment) { - cmd = cmd`--comment ${args.comment}`; - } - - const result = await cmd.text(); - - return { - success: true, - message: `Successfully reopened issue(s) #${args.issueNumbers.join(", ")}`, - issues: args.issueNumbers, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to reopen issue(s)", - message: error.message, - stderr: error.stderr?.toString(), - issues: args.issueNumbers, - }; - } - }, -}); \ No newline at end of file diff --git a/.opencode/tools/tea-issue-deps.ts b/.opencode/tools/tea-issue-deps.ts deleted file mode 100644 index 67ad115..0000000 --- a/.opencode/tools/tea-issue-deps.ts +++ /dev/null @@ -1,119 +0,0 @@ -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(), - }; - } - }, -}); diff --git a/.opencode/tools/tea-issue-update.ts b/.opencode/tools/tea-issue-update.ts deleted file mode 100644 index ad35326..0000000 --- a/.opencode/tools/tea-issue-update.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { tool } from "@opencode-ai/plugin"; -import { $ } from "bun"; - -export const issueUpdateTitle = tool({ - description: "Update the title of an issue", - args: { - issueNumber: tool.schema.number().describe("Issue number"), - title: tool.schema.string().describe("New title"), - }, - async execute(args) { - try { - const result = await $`tea issues edit --output json --title ${args.title} ${args.issueNumber}`.text(); - - return { - success: true, - message: `Successfully updated title for issue #${args.issueNumber}`, - issueNumber: args.issueNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to update issue title", - message: error.message, - stderr: error.stderr?.toString(), - issueNumber: args.issueNumber, - }; - } - }, -}); - -export const issueUpdateDescription = tool({ - description: "Update the description/body of an issue", - args: { - issueNumber: tool.schema.number().describe("Issue number"), - description: tool.schema.string().describe("New description/body"), - }, - async execute(args) { - try { - const result = await $`tea issues edit --output json --description ${args.description} ${args.issueNumber}`.text(); - - return { - success: true, - message: `Successfully updated description for issue #${args.issueNumber}`, - issueNumber: args.issueNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to update issue description", - message: error.message, - stderr: error.stderr?.toString(), - issueNumber: args.issueNumber, - }; - } - }, -}); - -export const issueAddLabels = tool({ - description: "Add labels to one or more issues", - args: { - issueNumbers: tool.schema - .array(tool.schema.number()) - .describe("Issue number(s) to add labels to"), - labels: tool.schema - .array(tool.schema.string()) - .describe("Label names to add"), - }, - async execute(args) { - try { - const issueListStr = args.issueNumbers.join(" "); - const labelsStr = args.labels.join(","); - - const result = await $`tea issues edit --output json --add-labels ${labelsStr} ${issueListStr}`.text(); - - return { - success: true, - message: `Successfully added label(s) "${labelsStr}" to issue(s) #${args.issueNumbers.join(", ")}`, - issueNumbers: args.issueNumbers, - labels: args.labels, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to add labels to issue(s)", - message: error.message, - stderr: error.stderr?.toString(), - issueNumbers: args.issueNumbers, - labels: args.labels, - }; - } - }, -}); - -export const issueRemoveLabels = tool({ - description: "Remove labels from one or more issues", - args: { - issueNumbers: tool.schema - .array(tool.schema.number()) - .describe("Issue number(s) to remove labels from"), - labels: tool.schema - .array(tool.schema.string()) - .describe("Label names to remove"), - }, - async execute(args) { - try { - const issueListStr = args.issueNumbers.join(" "); - const labelsStr = args.labels.join(","); - - const result = await $`tea issues edit --output json --remove-labels ${labelsStr} ${issueListStr}`.text(); - - return { - success: true, - message: `Successfully removed label(s) "${labelsStr}" from issue(s) #${args.issueNumbers.join(", ")}`, - issueNumbers: args.issueNumbers, - labels: args.labels, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to remove labels from issue(s)", - message: error.message, - stderr: error.stderr?.toString(), - issueNumbers: args.issueNumbers, - labels: args.labels, - }; - } - }, -}); - -export const issueAddComment = tool({ - description: "Add a comment to an issue", - args: { - issueNumber: tool.schema.number().describe("Issue number"), - comment: tool.schema.string().describe("Comment text"), - }, - async execute(args) { - try { - const result = await $`tea issue comment --output json --issue ${args.issueNumber} --body ${args.comment}`.text(); - - return { - success: true, - message: `Successfully added comment to issue #${args.issueNumber}`, - issueNumber: args.issueNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to add comment to issue", - message: error.message, - stderr: error.stderr?.toString(), - issueNumber: args.issueNumber, - }; - } - }, -}); \ No newline at end of file diff --git a/.opencode/tools/tea-issue.ts b/.opencode/tools/tea-issue.ts deleted file mode 100644 index 1b0c858..0000000 --- a/.opencode/tools/tea-issue.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { tool } from "@opencode-ai/plugin"; -import { $ } from "bun"; - -export const issueList = tool({ - description: - "List issues with filters for state, labels, assignee, milestone, and author", - args: { - state: tool.schema - .enum(["open", "closed", "all"]) - .default("open") - .describe("Filter by state"), - labels: tool.schema - .string() - .optional() - .describe("Comma-separated list of labels to match"), - assignee: tool.schema - .string() - .optional() - .describe("Filter by assignee username"), - milestone: tool.schema - .string() - .optional() - .describe("Filter by milestone name"), - author: tool.schema - .string() - .optional() - .describe("Filter by author username"), - limit: tool.schema - .number() - .default(30) - .describe("Number of issues to return"), - keyword: tool.schema - .string() - .optional() - .describe("Search keyword in title and body"), - }, - async execute(args, context) { - try { - let cmd = $`tea issue list --output json --state ${args.state} --limit ${args.limit ?? 30}`; - - if (args.labels && args.labels.length > 0) { - cmd = cmd`--labels ${args.labels}`; - } - - if (args.assignee && args.assignee.length > 0) { - cmd = cmd`--assignee ${args.assignee}`; - } - - if (args.milestone && args.milestone.length > 0) { - cmd = cmd`--milestones ${args.milestone}`; - } - - if (args.author && args.author.length > 0) { - cmd = cmd`--author ${args.author}`; - } - - if (args.keyword && args.keyword.length > 0) { - cmd = cmd`--keyword ${args.keyword}`; - } - - return await cmd.text(); - } catch (error: any) { - return { - error: "Failed to list issues", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); - -export const issueCreate = tool({ - description: - "Create a new issue with title, body, labels, milestone, and assignees", - args: { - title: tool.schema.string().describe("Issue title"), - body: tool.schema.string().optional().describe("Issue description/body"), - labels: tool.schema - .array(tool.schema.string()) - .optional() - .describe("Comma-separated list of label names"), - milestone: tool.schema.string().optional().describe("Milestone name"), - assignees: tool.schema - .array(tool.schema.string()) - .optional() - .describe("Comma-separated list of assignee usernames"), - }, - async execute(args, context) { - try { - let cmd = $`tea issue create --output json --title ${args.title}`; - - 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}`; - } - - if (args.assignees) { - cmd = cmd`--assignee ${args.assignees.join(",")}`; - } - - return await cmd.text(); - } catch (error: any) { - return { - error: "Failed to create issue", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); - -export const issueEdit = tool({ - description: - "Update an existing issue with partial updates to title, body, labels, milestone, or assignees", - args: { - issueNumber: tool.schema.number().describe("Issue number"), - title: tool.schema.string().optional().describe("New title"), - body: tool.schema.string().optional().describe("New description/body"), - labels: tool.schema - .array(tool.schema.string()) - .optional() - .describe("New comma-separated list of label names"), - milestone: tool.schema.string().optional().describe("New milestone name"), - assignees: tool.schema - .array(tool.schema.string()) - .optional() - .describe("New comma-separated list of assignee usernames"), - state: tool.schema - .enum(["open", "closed"]) - .optional() - .describe("New state"), - }, - async execute(args, context) { - try { - let cmd = $`tea issue edit --output json ${args.issueNumber}`; - - if (args.title) { - cmd = cmd`--title ${args.title}`; - } - - 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}`; - } - - if (args.assignees) { - cmd = cmd`--assignee ${args.assignees.join(",")}`; - } - - if (args.state) { - cmd = cmd`--state ${args.state}`; - } - - return await cmd.text(); - } catch (error: any) { - return { - error: "Failed to edit issue", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); - -export const issueDetails = tool({ - description: - "Get detailed information about a specific issue including dependencies and comments", - args: { - issueNumber: tool.schema.number().describe("Issue number"), - }, - async execute(args, context) { - try { - return await $`tea issue ${args.issueNumber} --output json --comments`.text(); - } catch (error: any) { - return { - error: "Failed to get issue details", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); \ No newline at end of file diff --git a/.opencode/tools/tea-label-update.ts b/.opencode/tools/tea-label-update.ts deleted file mode 100644 index 3f77295..0000000 --- a/.opencode/tools/tea-label-update.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { tool } from "@opencode-ai/plugin"; -import { $ } from "bun"; - -export const labelCreate = tool({ - description: "Create a new label with name, color, and optional description", - args: { - name: tool.schema.string().describe("Label name"), - color: tool.schema.string().describe("Hex color code (e.g., #e99695)"), - description: tool.schema - .string() - .optional() - .describe("Label description"), - }, - async execute(args) { - try { - let cmd = $`tea label create --output json --name ${args.name} --color ${args.color}`; - - if (args.description) { - cmd = cmd`--description ${args.description}`; - } - - const result = await cmd.text(); - return result; - } catch (error: any) { - return { - error: "Failed to create label", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); - -export const labelUpdate = tool({ - description: "Update an existing label's name, color, or description", - args: { - labelName: tool.schema.string().describe("Current label name"), - newName: tool.schema - .string() - .optional() - .describe("New label name"), - newColor: tool.schema - .string() - .optional() - .describe("New hex color code"), - newDescription: tool.schema - .string() - .optional() - .describe("New description"), - }, - async execute(args) { - try { - let cmd = $`tea label update --output json --name ${args.labelName}`; - - if (args.newName) { - cmd = cmd`--new-name ${args.newName}`; - } - - if (args.newColor) { - cmd = cmd`--new-color ${args.newColor}`; - } - - if (args.newDescription) { - cmd = cmd`--new-description ${args.newDescription}`; - } - - const result = await cmd.text(); - return result; - } catch (error: any) { - return { - error: "Failed to update label", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); - -export const labelDelete = tool({ - description: "Delete a label from the repository", - args: { - labelName: tool.schema.string().describe("Label name to delete"), - }, - async execute(args) { - try { - const result = await $`tea label delete --output json --name ${args.labelName}`.text(); - return { - success: true, - message: `Successfully deleted label "${args.labelName}"`, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to delete label", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -}); \ No newline at end of file diff --git a/.opencode/tools/tea-label.ts b/.opencode/tools/tea-label.ts deleted file mode 100644 index bd34ecb..0000000 --- a/.opencode/tools/tea-label.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" - -export const labelList = tool({ - description: "List available labels with their colors and descriptions", - args: {}, - async execute(args, context) { - try { - const result = await $`tea label list --output json`.text() - return result - } catch (error: any) { - return { - error: "Failed to list labels", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) \ No newline at end of file diff --git a/.opencode/tools/tea-milestone-update.ts b/.opencode/tools/tea-milestone-update.ts deleted file mode 100644 index 95a0cdc..0000000 --- a/.opencode/tools/tea-milestone-update.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { tool } from "@opencode-ai/plugin"; -import { $ } from "bun"; - -export const milestoneUpdate = tool({ - description: "Update an existing milestone with new title, description, due date, or state", - args: { - milestoneNumber: tool.schema.number().describe("Milestone number"), - title: tool.schema - .string() - .optional() - .describe("New milestone title"), - description: tool.schema - .string() - .optional() - .describe("New milestone description"), - dueDate: tool.schema - .string() - .optional() - .describe("New due date (format: YYYY-MM-DD)"), - state: tool.schema - .enum(["open", "closed"]) - .optional() - .describe("New milestone state"), - }, - async execute(args) { - try { - let cmd = $`tea milestone edit --output json ${args.milestoneNumber}`; - - if (args.title) { - cmd = cmd`--title ${args.title}`; - } - - if (args.description) { - cmd = cmd`--description ${args.description}`; - } - - if (args.dueDate) { - cmd = cmd`--due-date ${args.dueDate}`; - } - - if (args.state) { - cmd = cmd`--state ${args.state}`; - } - - const result = await cmd.text(); - - return { - success: true, - message: `Successfully updated milestone #${args.milestoneNumber}`, - milestoneNumber: args.milestoneNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to update milestone", - message: error.message, - stderr: error.stderr?.toString(), - milestoneNumber: args.milestoneNumber, - }; - } - }, -}); - -export const milestoneDelete = tool({ - description: "Delete a milestone from the repository", - args: { - milestoneNumber: tool.schema.number().describe("Milestone number to delete"), - confirm: tool.schema - .boolean() - .optional() - .describe("Confirmation flag (set to true to confirm deletion)"), - }, - async execute(args) { - try { - if (args.confirm !== true) { - return { - error: "Deletion not confirmed", - message: "Please set confirm: true to confirm deletion", - }; - } - - const result = await $`tea milestone delete --output json ${args.milestoneNumber}`.text(); - - return { - success: true, - message: `Successfully deleted milestone #${args.milestoneNumber}`, - milestoneNumber: args.milestoneNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to delete milestone", - message: error.message, - stderr: error.stderr?.toString(), - milestoneNumber: args.milestoneNumber, - }; - } - }, -}); \ No newline at end of file diff --git a/.opencode/tools/tea-milestone.ts b/.opencode/tools/tea-milestone.ts deleted file mode 100644 index 8a87cf2..0000000 --- a/.opencode/tools/tea-milestone.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" - -export const milestoneList = tool({ - description: "List milestones with their status and progress", - args: { - state: tool.schema.enum(["open", "closed", "all"]).default("open").describe("Filter by state"), - }, - async execute(args, context) { - try { - const result = await $`tea milestone list --output json --state ${args.state}`.text() - return result - } catch (error: any) { - return { - error: "Failed to list milestones", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) - -export const milestoneCreate = tool({ - description: "Create a new milestone with title, description, and optional due date", - args: { - title: tool.schema.string().describe("Milestone title"), - description: tool.schema.string().optional().describe("Milestone description"), - dueDate: tool.schema.string().optional().describe("Due date (format: YYYY-MM-DD)"), - }, - async execute(args, context) { - try { - let cmd = $`tea milestone create --output json --title ${args.title}` - - if (args.description) { - cmd = cmd`--description ${args.description}` - } - - if (args.dueDate) { - cmd = cmd`--due-date ${args.dueDate}` - } - - const result = await cmd.text() - return result - } catch (error: any) { - return { - error: "Failed to create milestone", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) \ No newline at end of file diff --git a/.opencode/tools/tea-notification.ts b/.opencode/tools/tea-notification.ts deleted file mode 100644 index 5010fa0..0000000 --- a/.opencode/tools/tea-notification.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { tool } from "@opencode-ai/plugin" -import { $ } from "bun" - -export const notificationList = tool({ - description: "List unread notifications including PR reviews, mentions, and other updates", - args: { - limit: tool.schema.number().default(30).describe("Number of notifications to return"), - }, - async execute(args, context) { - try { - const result = await $`tea notification list --output json --limit ${args.limit}`.text() - return result - } catch (error: any) { - return { - error: "Failed to list notifications", - message: error.message, - stderr: error.stderr?.toString(), - } - } - }, -}) \ No newline at end of file diff --git a/.opencode/tools/tea-pr-review.ts b/.opencode/tools/tea-pr-review.ts deleted file mode 100644 index 79a7469..0000000 --- a/.opencode/tools/tea-pr-review.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { tool } from "@opencode-ai/plugin"; -import { $ } from "bun"; - -export const prApprove = tool({ - description: "Approve a pull request with an optional comment", - args: { - prNumber: tool.schema.number().describe("Pull request number"), - comment: tool.schema - .string() - .optional() - .describe("Optional review comment"), - }, - async execute(args) { - try { - let cmd = $`tea pr review --output json --approve ${args.prNumber}`; - - if (args.comment) { - cmd = cmd`--message ${args.comment}`; - } - - const result = await cmd.text(); - - return { - success: true, - message: `Successfully approved PR #${args.prNumber}`, - prNumber: args.prNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to approve PR", - message: error.message, - stderr: error.stderr?.toString(), - prNumber: args.prNumber, - }; - } - }, -}); - -export const prRequestChanges = tool({ - description: "Request changes on a pull request with a comment", - args: { - prNumber: tool.schema.number().describe("Pull request number"), - comment: tool.schema.string().describe("Review comment explaining requested changes"), - }, - async execute(args) { - try { - const cmd = $`tea pr review --output json --request-changes ${args.prNumber} --message ${args.comment}`; - - const result = await cmd.text(); - - return { - success: true, - message: `Successfully requested changes on PR #${args.prNumber}`, - prNumber: args.prNumber, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to request changes on PR", - message: error.message, - stderr: error.stderr?.toString(), - prNumber: args.prNumber, - }; - } - }, -}); - -export const prRequestChangesWithFeedback = tool({ - description: "Request changes on a pull request with detailed feedback", - args: { - prNumber: tool.schema.number().describe("Pull request number"), - feedback: tool.schema.string().describe("Detailed feedback explaining requested changes"), - sections: tool.schema - .array(tool.schema.string()) - .optional() - .describe("Specific sections requiring changes (e.g., ['authentication', 'tests'])"), - }, - async execute(args) { - try { - let feedbackText = args.feedback; - - if (args.sections && args.sections.length > 0) { - feedbackText += "\n\nKey areas requiring attention:\n"; - for (const section of args.sections) { - feedbackText += `- ${section}\n`; - } - } - - const cmd = $`tea pr review --output json --request-changes ${args.prNumber} --message ${feedbackText}`; - - const result = await cmd.text(); - - return { - success: true, - message: `Successfully requested changes on PR #${args.prNumber}`, - prNumber: args.prNumber, - feedback: feedbackText, - output: result, - }; - } catch (error: any) { - return { - error: "Failed to request changes on PR", - message: error.message, - stderr: error.stderr?.toString(), - prNumber: args.prNumber, - }; - } - }, -}); \ No newline at end of file diff --git a/.opencode/tools/tea-pr.ts b/.opencode/tools/tea-pr.ts deleted file mode 100644 index 4e6e708..0000000 --- a/.opencode/tools/tea-pr.ts +++ /dev/null @@ -1,145 +0,0 @@ -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"), - limit: tool.schema.number().optional().describe("Number of PRs to return"), - }, - async execute(args, context) { - try { - const limit = args.limit || 30; - const cmd = $`tea pr list --output json --state ${args.state} --limit ${limit}`; - - const result = await cmd.text(); - return 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 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 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 result; - } catch (error: any) { - return { - error: "Failed to get pull request details", - message: error.message, - stderr: error.stderr?.toString(), - }; - } - }, -});