From c3beb370a5e83f68821ef3b7da3664ecc26401c8 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 1 May 2026 18:56:09 +0900 Subject: [PATCH] fix(doctor): detect gh when Bun.which misses it Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/cli/doctor/checks/tools-gh.test.ts | 35 ++++++++++++++++++++++++++ src/cli/doctor/checks/tools-gh.ts | 14 +++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/cli/doctor/checks/tools-gh.test.ts diff --git a/src/cli/doctor/checks/tools-gh.test.ts b/src/cli/doctor/checks/tools-gh.test.ts new file mode 100644 index 000000000..46eec87e5 --- /dev/null +++ b/src/cli/doctor/checks/tools-gh.test.ts @@ -0,0 +1,35 @@ +/// + +import { afterEach, describe, expect, it, mock } from "bun:test" + +const originalWhich = Bun.which + +afterEach(() => { + Bun.which = originalWhich + mock.restore() +}) + +describe("getGhCliInfo", () => { + it("falls back to gh --version when Bun.which cannot find gh", async () => { + // given + Bun.which = mock(() => null) + mock.module("../spawn-with-timeout", () => ({ + spawnWithTimeout: mock((command: string[]) => { + if (command.join(" ") === "gh --version") { + return Promise.resolve({ stdout: "gh version 2.82.1\n", stderr: "", exitCode: 0, timedOut: false }) + } + + return Promise.resolve({ stdout: "", stderr: "not logged in", exitCode: 1, timedOut: false }) + }), + })) + const { getGhCliInfo } = await import("./tools-gh") + + // when + const info = await getGhCliInfo() + + // then + expect(info.installed).toBe(true) + expect(info.version).toBe("2.82.1") + expect(info.path).toBe(null) + }) +}) diff --git a/src/cli/doctor/checks/tools-gh.ts b/src/cli/doctor/checks/tools-gh.ts index 71a539d1e..6839a71fc 100644 --- a/src/cli/doctor/checks/tools-gh.ts +++ b/src/cli/doctor/checks/tools-gh.ts @@ -80,6 +80,20 @@ async function getGhAuthStatus(): Promise<{ export async function getGhCliInfo(): Promise { const binaryStatus = await checkBinaryExists("gh") if (!binaryStatus.exists) { + const version = await getGhVersion() + if (version) { + const authStatus = await getGhAuthStatus() + return { + installed: true, + version, + path: null, + authenticated: authStatus.authenticated, + username: authStatus.username, + scopes: authStatus.scopes, + error: authStatus.error, + } + } + return { installed: false, version: null,