418cf8529f
Ripgrep's --glob flag silently returns zero results when the search target is an absolute path and the pattern contains directory prefixes (e.g. 'apps/backend/**/*.ts' with '/project'). This is a known ripgrep behavior where glob matching fails against paths rooted at absolute arguments. Fix by running ripgrep with cwd set to the search path and '.' as the search target, matching how the find backend already operates. Ripgrep then sees relative paths internally, so directory-prefixed globs match correctly. Output paths are resolved back to absolute via resolve().
50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
import { resolve } from "node:path"
|
|
import type { PluginInput } from "@opencode-ai/plugin"
|
|
import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool"
|
|
import { runRgFiles } from "./cli"
|
|
import { resolveGrepCliWithAutoInstall } from "./constants"
|
|
import { formatGlobResult } from "./result-formatter"
|
|
|
|
export function createGlobTools(ctx: PluginInput): Record<string, ToolDefinition> {
|
|
const glob: ToolDefinition = tool({
|
|
description:
|
|
"Fast file pattern matching tool with safety limits (60s timeout, 100 file limit). " +
|
|
"Supports glob patterns like \"**/*.js\" or \"src/**/*.ts\". " +
|
|
"Returns matching file paths sorted by modification time. " +
|
|
"Use this tool when you need to find files by name patterns.",
|
|
args: {
|
|
pattern: tool.schema.string().describe("The glob pattern to match files against"),
|
|
path: tool.schema
|
|
.string()
|
|
.optional()
|
|
.describe(
|
|
"The directory to search in. If not specified, the current working directory will be used. " +
|
|
"IMPORTANT: Omit this field to use the default directory. DO NOT enter \"undefined\" or \"null\" - " +
|
|
"simply omit it for the default behavior. Must be a valid directory path if provided."
|
|
),
|
|
},
|
|
execute: async (args, context) => {
|
|
try {
|
|
const cli = await resolveGrepCliWithAutoInstall()
|
|
const runtimeCtx = context as Record<string, unknown>
|
|
const dir = typeof runtimeCtx.directory === "string" ? runtimeCtx.directory : ctx.directory
|
|
const searchPath = args.path ? resolve(dir, args.path) : dir
|
|
|
|
const result = await runRgFiles(
|
|
{
|
|
pattern: args.pattern,
|
|
paths: [searchPath],
|
|
},
|
|
cli
|
|
)
|
|
|
|
return formatGlobResult(result)
|
|
} catch (e) {
|
|
return `Error: ${e instanceof Error ? e.message : String(e)}`
|
|
}
|
|
},
|
|
})
|
|
|
|
return { glob }
|
|
}
|