diff --git a/packages/opencode/src/cli/cmd/pr.ts b/packages/opencode/src/cli/cmd/pr.ts index 936cff7cc1..c61d951027 100644 --- a/packages/opencode/src/cli/cmd/pr.ts +++ b/packages/opencode/src/cli/cmd/pr.ts @@ -4,9 +4,30 @@ import { AppRuntime } from "@/effect/app-runtime" import { Git } from "@/git" import { Instance } from "@/project/instance" import { Process } from "@/util" +import { existsSync } from "node:fs" // kilocode_change + +const subcommand = "pr" // kilocode_change + +// kilocode_change start - resolve the currently running CLI instead of hardcoding opencode +export function cliCommand( + input = { + execPath: process.execPath, + argv: process.argv, + exists: existsSync, + }, +) { + const script = input.argv[1] + if (!script) return [input.execPath] + if (script === subcommand) return [input.execPath] // kilocode_change + if (script.startsWith("/$bunfs/root/")) return [input.execPath] + if (script.startsWith("B:/~BUN/root/")) return [input.execPath] + if (input.exists(script)) return [input.execPath, script] + return [input.execPath] +} +// kilocode_change end export const PrCommand = cmd({ - command: "pr ", + command: `${subcommand} `, // kilocode_change describe: "fetch and checkout a GitHub PR branch, then run kilo", // kilocode_change builder: (yargs) => yargs.positional("number", { @@ -26,6 +47,7 @@ export const PrCommand = cmd({ const prNumber = args.number const localBranchName = `pr/${prNumber}` + const cli = cliCommand() // kilocode_change UI.println(`Fetching and checking out PR #${prNumber}...`) // Use gh pr checkout with custom branch name @@ -102,9 +124,7 @@ export const PrCommand = cmd({ UI.println(`Found session: ${sessionUrl}`) UI.println(`Importing session...`) - const importResult = await Process.text(["kilo", "import", sessionUrl], { - nothrow: true, - }) + const importResult = await Process.text([...cli, "import", sessionUrl], { nothrow: true }) // kilocode_change end if (importResult.code === 0) { const importOutput = importResult.text.trim() @@ -122,13 +142,12 @@ export const PrCommand = cmd({ UI.println(`Successfully checked out PR #${prNumber} as branch '${localBranchName}'`) UI.println() - const bin = "kilo" // kilocode_change - UI.println(`Starting ${bin}...`) // kilocode_change + UI.println("Starting kilo...") // kilocode_change UI.println() - const opencodeArgs = sessionId ? ["-s", sessionId] : [] + const run = sessionId ? [...cli, "-s", sessionId] : cli // kilocode_change // kilocode_change start - const opencodeProcess = Process.spawn([bin, ...opencodeArgs], { + const opencodeProcess = Process.spawn(run, { // kilocode_change end stdin: "inherit", stdout: "inherit", @@ -136,7 +155,7 @@ export const PrCommand = cmd({ cwd: process.cwd(), }) const code = await opencodeProcess.exited - if (code !== 0) throw new Error(`${bin} exited with code ${code}`) // kilocode_change + if (code !== 0) throw new Error(`kilo exited with code ${code}`) // kilocode_change }, }) }, diff --git a/packages/opencode/test/cli/pr.test.ts b/packages/opencode/test/cli/pr.test.ts new file mode 100644 index 0000000000..6101784d5c --- /dev/null +++ b/packages/opencode/test/cli/pr.test.ts @@ -0,0 +1,60 @@ +// kilocode_change - new file +import { expect, test } from "bun:test" +import { cliCommand } from "../../src/cli/cmd/pr" + +test("cliCommand uses the current script when argv[1] is a file path", () => { + const result = cliCommand({ + execPath: "/usr/bin/node", + argv: ["/usr/bin/node", "/tmp/kilo.js", "pr", "1"], + exists: (file) => file === "/tmp/kilo.js", + }) + + expect(result).toEqual(["/usr/bin/node", "/tmp/kilo.js"]) +}) + +test("cliCommand falls back to execPath when argv[1] is a subcommand", () => { + const result = cliCommand({ + execPath: "/usr/local/bin/kilo", + argv: ["/usr/local/bin/kilo", "pr", "1"], + exists: () => false, + }) + + expect(result).toEqual(["/usr/local/bin/kilo"]) +}) + +test("cliCommand ignores subcommand token even when it exists on disk", () => { + const result = cliCommand({ + execPath: "/usr/local/bin/kilo", + argv: ["/usr/local/bin/kilo", "pr", "1"], + exists: (file) => file === "pr", + }) + + expect(result).toEqual(["/usr/local/bin/kilo"]) +}) + +test("cliCommand falls back to execPath when argv[1] is missing", () => { + const result = cliCommand({ + execPath: "/usr/local/bin/kilo", + argv: ["/usr/local/bin/kilo"], + exists: () => false, + }) + + expect(result).toEqual(["/usr/local/bin/kilo"]) +}) + +test("cliCommand falls back to execPath for bun virtual script paths", () => { + const unix = cliCommand({ + execPath: "/tmp/kilo", + argv: ["/tmp/kilo", "/$bunfs/root/src/index.js", "pr", "1"], + exists: () => true, + }) + + const win = cliCommand({ + execPath: "C:/tmp/kilo.exe", + argv: ["C:/tmp/kilo.exe", "B:/~BUN/root/src/index.js", "pr", "1"], + exists: () => true, + }) + + expect(unix).toEqual(["/tmp/kilo"]) + expect(win).toEqual(["C:/tmp/kilo.exe"]) +})