diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index ead3a0149b4..246214f07fe 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -990,6 +990,10 @@ export namespace Config { }, ), instructions: z.array(z.string()).optional().describe("Additional instruction files or patterns to include"), + respect_gitignore: z + .boolean() + .optional() + .describe("Respect .gitignore when searching files. Set to false to include gitignored files. Default: true"), layout: Layout.optional().describe("@deprecated Always uses stretch layout."), permission: Permission.optional(), tools: z.record(z.string(), z.boolean()).optional(), diff --git a/packages/opencode/src/file/ripgrep.ts b/packages/opencode/src/file/ripgrep.ts index 834cbee1ed1..0c09159a13c 100644 --- a/packages/opencode/src/file/ripgrep.ts +++ b/packages/opencode/src/file/ripgrep.ts @@ -211,10 +211,12 @@ export namespace Ripgrep { hidden?: boolean follow?: boolean maxDepth?: number + noIgnore?: boolean }) { const args = [await filepath(), "--files", "--glob=!.git/*"] if (input.follow !== false) args.push("--follow") if (input.hidden !== false) args.push("--hidden") + if (input.noIgnore) args.push("--no-ignore") if (input.maxDepth !== undefined) args.push(`--max-depth=${input.maxDepth}`) if (input.glob) { for (const g of input.glob) { @@ -373,9 +375,11 @@ export namespace Ripgrep { glob?: string[] limit?: number follow?: boolean + noIgnore?: boolean }) { const args = [`${await filepath()}`, "--json", "--hidden", "--glob='!.git/*'"] if (input.follow !== false) args.push("--follow") + if (input.noIgnore) args.push("--no-ignore") if (input.glob) { for (const g of input.glob) { diff --git a/packages/opencode/src/tool/glob.ts b/packages/opencode/src/tool/glob.ts index dda57f6ee1b..d58693f75de 100644 --- a/packages/opencode/src/tool/glob.ts +++ b/packages/opencode/src/tool/glob.ts @@ -5,6 +5,7 @@ import DESCRIPTION from "./glob.txt" import { Ripgrep } from "../file/ripgrep" import { Instance } from "../project/instance" import { assertExternalDirectory } from "./external-directory" +import { Config } from "../config/config" export const GlobTool = Tool.define("glob", { description: DESCRIPTION, @@ -32,12 +33,14 @@ export const GlobTool = Tool.define("glob", { search = path.isAbsolute(search) ? search : path.resolve(Instance.directory, search) await assertExternalDirectory(ctx, search, { kind: "directory" }) + const cfg = await Config.get() const limit = 100 const files = [] let truncated = false for await (const file of Ripgrep.files({ cwd: search, glob: [params.pattern], + noIgnore: cfg.respect_gitignore === false, })) { if (files.length >= limit) { truncated = true diff --git a/packages/opencode/src/tool/grep.ts b/packages/opencode/src/tool/grep.ts index ad62621e072..fd74215f19f 100644 --- a/packages/opencode/src/tool/grep.ts +++ b/packages/opencode/src/tool/grep.ts @@ -6,6 +6,7 @@ import DESCRIPTION from "./grep.txt" import { Instance } from "../project/instance" import path from "path" import { assertExternalDirectory } from "./external-directory" +import { Config } from "../config/config" const MAX_LINE_LENGTH = 2000 @@ -36,8 +37,10 @@ export const GrepTool = Tool.define("grep", { searchPath = path.isAbsolute(searchPath) ? searchPath : path.resolve(Instance.directory, searchPath) await assertExternalDirectory(ctx, searchPath, { kind: "directory" }) + const cfg = await Config.get() const rgPath = await Ripgrep.filepath() const args = ["-nH", "--hidden", "--follow", "--field-match-separator=|", "--regexp", params.pattern] + if (cfg.respect_gitignore === false) args.push("--no-ignore") if (params.include) { args.push("--glob", params.include) } diff --git a/packages/opencode/src/tool/ls.ts b/packages/opencode/src/tool/ls.ts index cc3d750078f..ce78b35c8d4 100644 --- a/packages/opencode/src/tool/ls.ts +++ b/packages/opencode/src/tool/ls.ts @@ -5,6 +5,7 @@ import DESCRIPTION from "./ls.txt" import { Instance } from "../project/instance" import { Ripgrep } from "../file/ripgrep" import { assertExternalDirectory } from "./external-directory" +import { Config } from "../config/config" export const IGNORE_PATTERNS = [ "node_modules/", @@ -54,9 +55,10 @@ export const ListTool = Tool.define("list", { }, }) + const cfg = await Config.get() const ignoreGlobs = IGNORE_PATTERNS.map((p) => `!${p}*`).concat(params.ignore?.map((p) => `!${p}`) || []) const files = [] - for await (const file of Ripgrep.files({ cwd: searchPath, glob: ignoreGlobs })) { + for await (const file of Ripgrep.files({ cwd: searchPath, glob: ignoreGlobs, noIgnore: cfg.respect_gitignore === false })) { files.push(file) if (files.length >= LIMIT) break }