summaryrefslogtreecommitdiffhomepage
path: root/.opencode/tool
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2026-05-03 01:21:17 -0400
committerDax Raad <[email protected]>2026-05-03 01:21:17 -0400
commita08e4c96514b791391c9b81ade129f6634ad57f7 (patch)
tree4cdb560e128b6f202b759f6a1abb5fade85081d2 /.opencode/tool
parent7ccab8d2729bb804c94e49c62df521026a6f80f2 (diff)
downloadopencode-a08e4c96514b791391c9b81ade129f6634ad57f7.tar.gz
opencode-a08e4c96514b791391c9b81ade129f6634ad57f7.zip
core: simplify triage workflow to focus on issue ownership
Switch triage agent to gpt-5.4-nano for faster issue assignment. Remove label management from the triage tool so it only assigns owners based on team ownership rules. This reduces noise in the issue tracker and ensures issues get to the right team member immediately without unnecessary labels. Update team structures to reflect current ownership and add script for processing unassigned issues.
Diffstat (limited to '.opencode/tool')
-rw-r--r--.opencode/tool/github-triage.ts78
1 files changed, 10 insertions, 68 deletions
diff --git a/.opencode/tool/github-triage.ts b/.opencode/tool/github-triage.ts
index 56886808a..e03b1fdd9 100644
--- a/.opencode/tool/github-triage.ts
+++ b/.opencode/tool/github-triage.ts
@@ -1,16 +1,14 @@
/// <reference path="../env.d.ts" />
import { tool } from "@opencode-ai/plugin"
+
const TEAM = {
- desktop: ["adamdotdevin", "iamdavidhill", "Brendonovich", "nexxeln"],
- zen: ["fwang", "MrMushrooooom"],
- tui: ["kommander", "rekram1-node", "simonklee"],
- core: ["kitlangton", "rekram1-node", "jlongster"],
- docs: ["R44VC0RP"],
+ tui: ["kommander", "simonklee"],
+ desktop_web: ["Hona", "Brendonovich"],
+ core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton"],
+ inference: ["fwang", "MrMushrooooom"],
windows: ["Hona"],
} as const
-const ASSIGNEES = [...new Set(Object.values(TEAM).flat())]
-
function pick<T>(items: readonly T[]) {
return items[Math.floor(Math.random() * items.length)]!
}
@@ -38,79 +36,23 @@ async function githubFetch(endpoint: string, options: RequestInit = {}) {
}
export default tool({
- description: `Use this tool to assign and/or label a GitHub issue.
+ description: `Use this tool to assign a GitHub issue.
-Choose labels and assignee using the current triage policy and ownership rules.
-Pick the most fitting labels for the issue and assign one owner.
-
-If unsure, choose the team/section with the most overlap with the issue and assign a member from that team at random.`,
+Provide the team that should own the issue. This tool picks a random assignee from that team and does not apply labels.`,
args: {
- assignee: tool.schema
- .enum(ASSIGNEES as [string, ...string[]])
- .describe("The username of the assignee")
- .default("rekram1-node"),
- labels: tool.schema
- .array(tool.schema.enum(["nix", "opentui", "perf", "web", "desktop", "zen", "docs", "windows", "core"]))
- .describe("The labels(s) to add to the issue")
- .default([]),
+ team: tool.schema.enum(Object.keys(TEAM) as [keyof typeof TEAM, ...(keyof typeof TEAM)[]]).describe("The owning team"),
},
async execute(args) {
const issue = getIssueNumber()
const owner = "anomalyco"
const repo = "opencode"
-
- const results: string[] = []
- let labels = [...new Set(args.labels.map((x) => (x === "desktop" ? "web" : x)))]
- const web = labels.includes("web")
- const text = `${process.env.ISSUE_TITLE ?? ""}\n${process.env.ISSUE_BODY ?? ""}`.toLowerCase()
- const zen = /\bzen\b/.test(text) || text.includes("opencode black")
- const nix = /\bnix(os)?\b/.test(text)
-
- if (labels.includes("nix") && !nix) {
- labels = labels.filter((x) => x !== "nix")
- results.push("Dropped label: nix (issue does not mention nix)")
- }
-
- const assignee = nix ? "rekram1-node" : web ? pick(TEAM.desktop) : args.assignee
-
- if (labels.includes("zen") && !zen) {
- throw new Error("Only add the zen label when issue title/body contains 'zen'")
- }
-
- if (web && !nix && !(TEAM.desktop as readonly string[]).includes(assignee)) {
- throw new Error("Web issues must be assigned to adamdotdevin, iamdavidhill, Brendonovich, or nexxeln")
- }
-
- if ((TEAM.zen as readonly string[]).includes(assignee) && !labels.includes("zen")) {
- throw new Error("Only zen issues should be assigned to fwang or MrMushrooooom")
- }
-
- if (assignee === "Hona" && !labels.includes("windows")) {
- throw new Error("Only windows issues should be assigned to Hona")
- }
-
- if (assignee === "R44VC0RP" && !labels.includes("docs")) {
- throw new Error("Only docs issues should be assigned to R44VC0RP")
- }
-
- if (assignee === "kommander" && !labels.includes("opentui")) {
- throw new Error("Only opentui issues should be assigned to kommander")
- }
+ const assignee = pick(TEAM[args.team])
await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/assignees`, {
method: "POST",
body: JSON.stringify({ assignees: [assignee] }),
})
- results.push(`Assigned @${assignee} to issue #${issue}`)
-
- if (labels.length > 0) {
- await githubFetch(`/repos/${owner}/${repo}/issues/${issue}/labels`, {
- method: "POST",
- body: JSON.stringify({ labels }),
- })
- results.push(`Added labels: ${labels.join(", ")}`)
- }
- return results.join("\n")
+ return `Assigned @${assignee} from ${args.team} to issue #${issue}`
},
})