From 12c2d86c84ecfce118ffb5b4db7ed4155bbca8fc Mon Sep 17 00:00:00 2001 From: Alex Alecu Date: Thu, 23 Apr 2026 16:46:22 +0300 Subject: [PATCH] feat(cli): show open PR for current branch in sidebar --- .changeset/cli-sidebar-pr.md | 5 ++ .../src/cli/cmd/tui/plugin/internal.ts | 2 + .../src/kilocode/plugins/sidebar-pr.tsx | 72 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 .changeset/cli-sidebar-pr.md create mode 100644 packages/opencode/src/kilocode/plugins/sidebar-pr.tsx diff --git a/.changeset/cli-sidebar-pr.md b/.changeset/cli-sidebar-pr.md new file mode 100644 index 00000000000..3e3bad0cd3c --- /dev/null +++ b/.changeset/cli-sidebar-pr.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": minor +--- + +Show the open GitHub PR for the current branch in the session sidebar. diff --git a/packages/opencode/src/cli/cmd/tui/plugin/internal.ts b/packages/opencode/src/cli/cmd/tui/plugin/internal.ts index 6a7892af7d4..1b256cd9390 100644 --- a/packages/opencode/src/cli/cmd/tui/plugin/internal.ts +++ b/packages/opencode/src/cli/cmd/tui/plugin/internal.ts @@ -5,6 +5,7 @@ import HomeNews from "@/kilocode/plugins/home-news" import HomeOnboarding from "@/kilocode/plugins/home-onboarding" import KiloHomeFooter from "@/kilocode/plugins/home-footer" import KiloSidebarFooter from "@/kilocode/plugins/sidebar-footer" +import KiloSidebarPr from "@/kilocode/plugins/sidebar-pr" import KiloSidebarUsage from "@/kilocode/plugins/sidebar-usage" // kilocode_change end import SidebarContext from "../feature-plugins/sidebar/context" @@ -26,6 +27,7 @@ export const INTERNAL_TUI_PLUGINS: InternalTuiPlugin[] = [ HomeOnboarding, // kilocode_change KiloHomeFooter, // kilocode_change KiloSidebarFooter, // kilocode_change + KiloSidebarPr, // kilocode_change KiloSidebarUsage, // kilocode_change HomeFooter, HomeTips, diff --git a/packages/opencode/src/kilocode/plugins/sidebar-pr.tsx b/packages/opencode/src/kilocode/plugins/sidebar-pr.tsx new file mode 100644 index 00000000000..96c5c89a1d9 --- /dev/null +++ b/packages/opencode/src/kilocode/plugins/sidebar-pr.tsx @@ -0,0 +1,72 @@ +// kilocode_change - new file +import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@kilocode/plugin/tui" +import { createResource, Show } from "solid-js" +import { Process } from "@/util" + +const id = "internal:kilo-sidebar-pr" + +type Pr = { number: number; title: string } + +async function lookup(cwd: string, branch: string): Promise { + // Try the tracking ref first (works when PR was checked out via `gh pr checkout` + // or when the branch's upstream is a fork). Fall back to an explicit branch + // lookup (works for same-repo branches pushed to origin). + const build = (b?: string) => { + const a = ["gh", "pr", "view"] + if (b) a.push(b) + a.push("--json", "number,title") + return a + } + for (const cmd of [build(), build(branch)]) { + const res = await Process.text(cmd, { cwd, nothrow: true, timeout: 15_000 }) + if (res.code !== 0) continue + const text = res.text.trim() + if (!text) continue + const data = JSON.parse(text) as Partial + if (typeof data.number === "number" && typeof data.title === "string") { + return { number: data.number, title: data.title } + } + } + return null +} + +function View(props: { api: TuiPluginApi }) { + const theme = () => props.api.theme.current + const branch = () => props.api.state.vcs?.branch + const cwd = () => props.api.state.path.directory + + const source = () => { + const b = branch() + const d = cwd() + if (!b || !d) return false + return { branch: b, cwd: d } + } + + const [pr] = createResource(source, async (s) => { + if (!s) return null + return lookup(s.cwd, s.branch).catch(() => null) + }) + + return ( + + + PR #{pr()!.number} - {pr()!.title} + + + ) +} + +const tui: TuiPlugin = async (api) => { + api.slots.register({ + order: 50, + slots: { + sidebar_content(_ctx, _props) { + return + }, + }, + }) +} + +const plugin: TuiPluginModule & { id: string } = { id, tui } + +export default plugin