mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-21 05:52:35 +08:00
feat(cli): show open PR for current branch in sidebar
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@kilocode/cli": minor
|
||||
---
|
||||
|
||||
Show the open GitHub PR for the current branch in the session sidebar.
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Pr | null> {
|
||||
// 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<Pr>
|
||||
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 (
|
||||
<Show when={pr()}>
|
||||
<text fg={theme().textMuted}>
|
||||
PR #{pr()!.number} - {pr()!.title}
|
||||
</text>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
|
||||
const tui: TuiPlugin = async (api) => {
|
||||
api.slots.register({
|
||||
order: 50,
|
||||
slots: {
|
||||
sidebar_content(_ctx, _props) {
|
||||
return <View api={api} />
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const plugin: TuiPluginModule & { id: string } = { id, tui }
|
||||
|
||||
export default plugin
|
||||
Reference in New Issue
Block a user