46 lines · 1.8 KB · TypeScript
RawDownload
import { existsSync } from "node:fs";import path from "node:path"; // Where the `gh` CLI is on this machine, if anywhere.//// The github extension is a thin wrapper over `gh`, so loading it where no gh// exists would advertise a dozen tools that all fail the same way. Presence is// the gate; being signed in is a separate question the extension's// `github_status` tool asks at call time, because a token can expire between// session start and the call that needs it.//// Resolved by walking PATH rather than spawning `gh --version`: this runs on// every session start. The resolved path is then handed to the extension, so// the tool calls run the same binary this check found instead of trusting the// child's PATH to agree. let cached: string | null | undefined; function searchPath(): string[] {  const fromEnv = (process.env.PATH ?? "").split(path.delimiter).filter(Boolean);  // A packaged desktop app is launched by the window server with a minimal  // PATH, so the Homebrew/MacPorts locations a user installed gh into are not  // on it. Probe them too rather than reporting gh missing on a machine that  // plainly has it.  return [...fromEnv, "/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/opt/local/bin"];} function locateGithubCli(): string | null {  const override = process.env.LOCAL_STUDIO_GH_PATH?.trim();  if (override) return existsSync(override) ? override : null;  const binary = process.platform === "win32" ? "gh.exe" : "gh";  for (const dir of searchPath()) {    const candidate = path.join(dir, binary);    if (existsSync(candidate)) return candidate;  }  return null;} export function githubCliPathSync(): string | null {  if (cached === undefined) cached = locateGithubCli();  return cached;} export function hasGithubCliSync(): boolean {  return githubCliPathSync() !== null;}