diff --git a/src/tools/grep/cli.ts b/src/tools/grep/cli.ts index c44bda377..1a6cd89d0 100644 --- a/src/tools/grep/cli.ts +++ b/src/tools/grep/cli.ts @@ -1,6 +1,7 @@ import { spawn } from "bun" import { resolveGrepCli, + type ResolvedCli, type GrepBackend, DEFAULT_MAX_DEPTH, DEFAULT_MAX_FILESIZE, @@ -148,17 +149,17 @@ function parseCountOutput(output: string): CountResult[] { return results } -export async function runRg(options: GrepOptions): Promise { +export async function runRg(options: GrepOptions, resolvedCli?: ResolvedCli): Promise { await rgSemaphore.acquire() try { - return await runRgInternal(options) + return await runRgInternal(options, resolvedCli) } finally { rgSemaphore.release() } } -async function runRgInternal(options: GrepOptions): Promise { - const cli = resolveGrepCli() +async function runRgInternal(options: GrepOptions, resolvedCli?: ResolvedCli): Promise { + const cli = resolvedCli ?? resolveGrepCli() const args = buildArgs(options, cli.backend) const timeout = Math.min(options.timeout ?? DEFAULT_TIMEOUT_MS, DEFAULT_TIMEOUT_MS) @@ -224,17 +225,23 @@ async function runRgInternal(options: GrepOptions): Promise { } } -export async function runRgCount(options: Omit): Promise { +export async function runRgCount( + options: Omit, + resolvedCli?: ResolvedCli +): Promise { await rgSemaphore.acquire() try { - return await runRgCountInternal(options) + return await runRgCountInternal(options, resolvedCli) } finally { rgSemaphore.release() } } -async function runRgCountInternal(options: Omit): Promise { - const cli = resolveGrepCli() +async function runRgCountInternal( + options: Omit, + resolvedCli?: ResolvedCli +): Promise { + const cli = resolvedCli ?? resolveGrepCli() const args = buildArgs({ ...options, context: 0 }, cli.backend) if (cli.backend === "rg") { diff --git a/src/tools/grep/constants.ts b/src/tools/grep/constants.ts index 524fddd4b..f41284324 100644 --- a/src/tools/grep/constants.ts +++ b/src/tools/grep/constants.ts @@ -3,10 +3,11 @@ import { join, dirname } from "node:path" import { spawnSync } from "node:child_process" import { getInstalledRipgrepPath, downloadAndInstallRipgrep } from "./downloader" import { getDataDir } from "../../shared/data-path" +import { log } from "../../shared/logger" export type GrepBackend = "rg" | "grep" -interface ResolvedCli { +export interface ResolvedCli { path: string backend: GrepBackend } @@ -89,7 +90,7 @@ export function resolveGrepCli(): ResolvedCli { export async function resolveGrepCliWithAutoInstall(): Promise { const current = resolveGrepCli() - if (current.backend === "rg") { + if (current.backend === "rg" && current.path !== "rg") { return current } @@ -103,7 +104,18 @@ export async function resolveGrepCliWithAutoInstall(): Promise { const rgPath = await downloadAndInstallRipgrep() cachedCli = { path: rgPath, backend: "rg" } return cachedCli - } catch { + } catch (error) { + if (current.backend === "grep") { + log("[oh-my-opencode] Failed to auto-install ripgrep. Falling back to GNU grep.", { + error: error instanceof Error ? error.message : String(error), + grep_path: current.path, + }) + } else { + log("[oh-my-opencode] Failed to auto-install ripgrep and GNU grep was not found.", { + error: error instanceof Error ? error.message : String(error), + }) + } + return current } } diff --git a/src/tools/grep/tools.ts b/src/tools/grep/tools.ts index b00c47540..eaf8a3972 100644 --- a/src/tools/grep/tools.ts +++ b/src/tools/grep/tools.ts @@ -2,6 +2,7 @@ import { resolve } from "node:path" import type { PluginInput } from "@opencode-ai/plugin" import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool" import { runRg, runRgCount } from "./cli" +import { resolveGrepCliWithAutoInstall } from "./constants" import { formatGrepResult, formatCountResult } from "./result-formatter" export function createGrepTools(ctx: PluginInput): Record { @@ -42,13 +43,14 @@ export function createGrepTools(ctx: PluginInput): Record 0 ? results.slice(0, headLimit) : results return formatCountResult(limited) } @@ -60,7 +62,7 @@ export function createGrepTools(ctx: PluginInput): Record