summaryrefslogtreecommitdiffhomepage
path: root/.opencode
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
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')
-rw-r--r--.opencode/agent/triage.md26
-rw-r--r--.opencode/tool/github-triage.ts78
2 files changed, 17 insertions, 87 deletions
diff --git a/.opencode/agent/triage.md b/.opencode/agent/triage.md
index a4c8454a9..03df339cb 100644
--- a/.opencode/agent/triage.md
+++ b/.opencode/agent/triage.md
@@ -1,7 +1,7 @@
---
mode: primary
hidden: true
-model: opencode/qwen3.6-plus
+model: opencode/gpt-5.4-nano
color: "#44BA81"
tools:
"*": false
@@ -14,7 +14,11 @@ Use your github-triage tool to triage issues.
This file is the source of truth for ownership/routing rules.
-Assign issues by choosing the team with the strongest overlap, then assign a member from that team at random.
+Assign issues by choosing the team with the strongest overlap. The github-triage tool will assign a random member from that team.
+
+Do not add labels to issues. Only assign an owner.
+
+When calling github-triage, pass one of these team values: tui, desktop_web, core, inference, windows.
## Teams
@@ -22,34 +26,18 @@ Assign issues by choosing the team with the strongest overlap, then assign a mem
Terminal UI issues, including rendering, keybindings, scrolling, terminal compatibility, SSH behavior, crashes in the TUI, and low-level TUI performance.
-- kommander
-- simonklee
-
### Desktop / Web
Desktop application and browser-based app issues, including `opencode web`, desktop-specific UI behavior, packaging, and web view problems.
-- Hona
-- Brendonovich
-
### Core
-Core opencode server and harness issues, including sqlite, snapshots, memory, API behavior, agent context construction, tool execution, provider integrations, model behavior, and larger architectural features.
-
-- jlongster
-- rekram1-node
-- nexxeln
-- kitlangton
+Core opencode server and harness issues, including sqlite, snapshots, memory, API behavior, agent context construction, tool execution, provider integrations, model behavior, documentation, and larger architectural features.
### Inference
OpenCode Zen, OpenCode Go, and billing issues.
-- fwang
-- MrMushrooooom
-
### Windows
Windows-specific issues, including native Windows behavior, WSL interactions, path handling, shell compatibility, and installation or runtime problems that only happen on Windows.
-
-- Hona
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}`
},
})