diff --git a/.gitignore b/.gitignore index 39f8c633b..6b9b9d77f 100644 --- a/.gitignore +++ b/.gitignore @@ -232,6 +232,7 @@ rulesync.local.jsonc **/.agents/skills/ **/.agents/rules/ **/GEMINI.md +**/.geminiignore **/.agents/workflows/ **/.agents/mcp_config.json **/.agents/hooks.json @@ -280,7 +281,6 @@ rulesync.local.jsonc **/.gemini/commands/ **/.gemini/agents/ **/.gemini/skills/ -**/.geminiignore **/.gemini/memories/ **/.goosehints **/.goose/ diff --git a/README.md b/README.md index 028066914..ce9918c5e 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ The tables below show whether each tool supports a given feature (✅ = supporte | Qwen Code | ✅ | ✅ | | | | | | ✅ | | Kiro | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Google Antigravity IDE | ✅ | | ✅ | ✅ | | ✅ | ✅ | | -| Google Antigravity CLI | ✅ | | ✅ | | | ✅ | ✅ | ✅ | +| Google Antigravity CLI | ✅ | ✅ | ✅ | | | ✅ | ✅ | ✅ | | Google Antigravity ⚠️ | ✅ | | | ✅ | | ✅ | | | | JetBrains Junie | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | AugmentCode | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | diff --git a/docs/reference/file-formats.md b/docs/reference/file-formats.md index 9393b8e0a..cecc50563 100644 --- a/docs/reference/file-formats.md +++ b/docs/reference/file-formats.md @@ -577,7 +577,9 @@ credentials/ ### Where ignore patterns are written per tool Most tools get a dedicated ignore file (for example `.cursorignore`, -`.geminiignore`, `.clineignore`). Claude Code is the exception: it does not +`.geminiignore`, `.clineignore`). Antigravity CLI is built on the same engine +as Gemini CLI, so it shares the `.geminiignore` file (enabling either target +writes it). Claude Code is the exception: it does not read a separate ignore file, so Rulesync writes the deny list into Claude Code's settings file as `permissions.deny` entries (`Read()`). diff --git a/docs/reference/supported-tools.md b/docs/reference/supported-tools.md index 7d816a2a6..bf0dc69c6 100644 --- a/docs/reference/supported-tools.md +++ b/docs/reference/supported-tools.md @@ -25,7 +25,7 @@ Rulesync supports both **generation** and **import** for All of the major AI cod | Qwen Code | qwencode | ✅ | ✅ | | | | | | ✅ 🌏 | | Kiro | kiro | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Google Antigravity IDE | antigravity-ide | ✅ 🌏 | | ✅ 🌏 🔧 | ✅ 🌏 | | ✅ 🌏 | ✅ 🌏 | | -| Google Antigravity CLI | antigravity-cli | ✅ 🌏 | | ✅ 🌏 🔧 | | | ✅ 🌏 | ✅ 🌏 | 🌏 | +| Google Antigravity CLI | antigravity-cli | ✅ 🌏 | ✅ | ✅ 🌏 🔧 | | | ✅ 🌏 | ✅ 🌏 | 🌏 | | Google Antigravity ⚠️ | antigravity | ✅ | | | ✅ | | ✅ 🌏 | | | | JetBrains Junie | junie | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | 🌏 | | | AugmentCode | augmentcode | ✅ 🌏 | ✅ | 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | diff --git a/skills/rulesync/file-formats.md b/skills/rulesync/file-formats.md index 9393b8e0a..cecc50563 100644 --- a/skills/rulesync/file-formats.md +++ b/skills/rulesync/file-formats.md @@ -577,7 +577,9 @@ credentials/ ### Where ignore patterns are written per tool Most tools get a dedicated ignore file (for example `.cursorignore`, -`.geminiignore`, `.clineignore`). Claude Code is the exception: it does not +`.geminiignore`, `.clineignore`). Antigravity CLI is built on the same engine +as Gemini CLI, so it shares the `.geminiignore` file (enabling either target +writes it). Claude Code is the exception: it does not read a separate ignore file, so Rulesync writes the deny list into Claude Code's settings file as `permissions.deny` entries (`Read()`). diff --git a/skills/rulesync/supported-tools.md b/skills/rulesync/supported-tools.md index 7d816a2a6..bf0dc69c6 100644 --- a/skills/rulesync/supported-tools.md +++ b/skills/rulesync/supported-tools.md @@ -25,7 +25,7 @@ Rulesync supports both **generation** and **import** for All of the major AI cod | Qwen Code | qwencode | ✅ | ✅ | | | | | | ✅ 🌏 | | Kiro | kiro | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Google Antigravity IDE | antigravity-ide | ✅ 🌏 | | ✅ 🌏 🔧 | ✅ 🌏 | | ✅ 🌏 | ✅ 🌏 | | -| Google Antigravity CLI | antigravity-cli | ✅ 🌏 | | ✅ 🌏 🔧 | | | ✅ 🌏 | ✅ 🌏 | 🌏 | +| Google Antigravity CLI | antigravity-cli | ✅ 🌏 | ✅ | ✅ 🌏 🔧 | | | ✅ 🌏 | ✅ 🌏 | 🌏 | | Google Antigravity ⚠️ | antigravity | ✅ | | | ✅ | | ✅ 🌏 | | | | JetBrains Junie | junie | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | 🌏 | | | AugmentCode | augmentcode | ✅ 🌏 | ✅ | 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | diff --git a/src/cli/commands/gitignore-entries.ts b/src/cli/commands/gitignore-entries.ts index ff4020d04..082408904 100644 --- a/src/cli/commands/gitignore-entries.ts +++ b/src/cli/commands/gitignore-entries.ts @@ -65,6 +65,7 @@ export const GITIGNORE_ENTRY_REGISTRY: ReadonlyArray = [ entry: "**/.agents/rules/", }, { target: "antigravity-cli", feature: "rules", entry: "**/GEMINI.md" }, + { target: "antigravity-cli", feature: "ignore", entry: "**/.geminiignore" }, { target: "antigravity-ide", feature: "commands", diff --git a/src/e2e/e2e-ignore.spec.ts b/src/e2e/e2e-ignore.spec.ts index 6ec98cc2a..8f3113244 100644 --- a/src/e2e/e2e-ignore.spec.ts +++ b/src/e2e/e2e-ignore.spec.ts @@ -17,6 +17,7 @@ describe("E2E: ignore", () => { format: "json" as const, }, { target: "geminicli", outputPath: ".geminiignore", format: "plaintext" as const }, + { target: "antigravity-cli", outputPath: ".geminiignore", format: "plaintext" as const }, { target: "goose", outputPath: ".gooseignore", format: "plaintext" as const }, { target: "cline", outputPath: ".clineignore", format: "plaintext" as const }, { target: "kilo", outputPath: ".kilocodeignore", format: "plaintext" as const }, @@ -70,6 +71,7 @@ credentials/ { target: "cursor", orphanPath: ".cursorignore" }, // claudecode uses settings.json (isDeletable=false) — excluded { target: "geminicli", orphanPath: ".geminiignore" }, + { target: "antigravity-cli", orphanPath: ".geminiignore" }, { target: "goose", orphanPath: ".gooseignore" }, { target: "cline", orphanPath: ".clineignore" }, { target: "kilo", orphanPath: ".kilocodeignore" }, @@ -134,6 +136,7 @@ describe("E2E: ignore (import)", () => { it.each([ { target: "cursor", sourcePath: ".cursorignore" }, { target: "geminicli", sourcePath: ".geminiignore" }, + { target: "antigravity-cli", sourcePath: ".geminiignore" }, { target: "goose", sourcePath: ".gooseignore" }, { target: "cline", sourcePath: ".clineignore" }, { target: "kilo", sourcePath: ".kilocodeignore" }, diff --git a/src/features/ignore/antigravity-cli-ignore.test.ts b/src/features/ignore/antigravity-cli-ignore.test.ts new file mode 100644 index 000000000..a0130767f --- /dev/null +++ b/src/features/ignore/antigravity-cli-ignore.test.ts @@ -0,0 +1,366 @@ +import { join } from "node:path"; + +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { + RULESYNC_AIIGNORE_FILE_NAME, + RULESYNC_RELATIVE_DIR_PATH, +} from "../../constants/rulesync-paths.js"; +import { setupTestDirectory } from "../../test-utils/test-directories.js"; +import { ensureDir, writeFileContent } from "../../utils/file.js"; +import { AntigravityCliIgnore } from "./antigravity-cli-ignore.js"; +import { RulesyncIgnore } from "./rulesync-ignore.js"; + +describe("AntigravityCliIgnore", () => { + let testDir: string; + let cleanup: () => Promise; + + beforeEach(async () => { + ({ testDir, cleanup } = await setupTestDirectory()); + vi.spyOn(process, "cwd").mockReturnValue(testDir); + }); + + afterEach(async () => { + await cleanup(); + vi.restoreAllMocks(); + }); + + describe("constructor", () => { + it("should create instance with default parameters", () => { + const antigravityCliIgnore = new AntigravityCliIgnore({ + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent: "*.log\nnode_modules/", + }); + + expect(antigravityCliIgnore).toBeInstanceOf(AntigravityCliIgnore); + expect(antigravityCliIgnore.getRelativeDirPath()).toBe("."); + expect(antigravityCliIgnore.getRelativeFilePath()).toBe(".geminiignore"); + expect(antigravityCliIgnore.getFileContent()).toBe("*.log\nnode_modules/"); + }); + + it("should create instance with custom outputRoot", () => { + const antigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: "/custom/path", + relativeDirPath: "subdir", + relativeFilePath: ".geminiignore", + fileContent: "*.tmp", + }); + + expect(antigravityCliIgnore.getFilePath()).toBe("/custom/path/subdir/.geminiignore"); + }); + + it("should validate content by default", () => { + expect(() => { + const _instance = new AntigravityCliIgnore({ + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent: "", // empty content should be valid + }); + }).not.toThrow(); + }); + + it("should skip validation when validate=false", () => { + expect(() => { + const _instance = new AntigravityCliIgnore({ + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent: "any content", + validate: false, + }); + }).not.toThrow(); + }); + }); + + describe("getSettablePaths", () => { + it("should return the project-root .geminiignore path", () => { + const paths = AntigravityCliIgnore.getSettablePaths(); + + expect(paths.relativeDirPath).toBe("."); + expect(paths.relativeFilePath).toBe(".geminiignore"); + }); + }); + + describe("toRulesyncIgnore", () => { + it("should convert to RulesyncIgnore with same content", () => { + const fileContent = "*.log\nnode_modules/\n.env"; + const antigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: testDir, + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent, + }); + + const rulesyncIgnore = antigravityCliIgnore.toRulesyncIgnore(); + + expect(rulesyncIgnore).toBeInstanceOf(RulesyncIgnore); + expect(rulesyncIgnore.getFileContent()).toBe(fileContent); + expect(rulesyncIgnore.getRelativeDirPath()).toBe(RULESYNC_RELATIVE_DIR_PATH); + expect(rulesyncIgnore.getRelativeFilePath()).toBe(RULESYNC_AIIGNORE_FILE_NAME); + }); + + it("should handle empty content", () => { + const antigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: testDir, + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent: "", + }); + + const rulesyncIgnore = antigravityCliIgnore.toRulesyncIgnore(); + + expect(rulesyncIgnore.getFileContent()).toBe(""); + }); + + it("should preserve patterns and formatting", () => { + const fileContent = "# Generated files\n*.log\n*.tmp\n\n# Dependencies\nnode_modules/\n.env*"; + const antigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: testDir, + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent, + }); + + const rulesyncIgnore = antigravityCliIgnore.toRulesyncIgnore(); + + expect(rulesyncIgnore.getFileContent()).toBe(fileContent); + }); + }); + + describe("fromRulesyncIgnore", () => { + it("should create AntigravityCliIgnore from RulesyncIgnore with default outputRoot", () => { + const fileContent = "*.log\nnode_modules/\n.env"; + const rulesyncIgnore = new RulesyncIgnore({ + relativeDirPath: ".rulesync", + relativeFilePath: ".rulesignore", + fileContent, + }); + + const antigravityCliIgnore = AntigravityCliIgnore.fromRulesyncIgnore({ + rulesyncIgnore, + }); + + expect(antigravityCliIgnore).toBeInstanceOf(AntigravityCliIgnore); + expect(antigravityCliIgnore.getOutputRoot()).toBe(testDir); + expect(antigravityCliIgnore.getRelativeDirPath()).toBe("."); + expect(antigravityCliIgnore.getRelativeFilePath()).toBe(".geminiignore"); + expect(antigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + + it("should create AntigravityCliIgnore from RulesyncIgnore with custom outputRoot", () => { + const fileContent = "*.tmp\nbuild/"; + const rulesyncIgnore = new RulesyncIgnore({ + relativeDirPath: ".rulesync", + relativeFilePath: ".rulesignore", + fileContent, + }); + + const antigravityCliIgnore = AntigravityCliIgnore.fromRulesyncIgnore({ + outputRoot: "/custom/base", + rulesyncIgnore, + }); + + expect(antigravityCliIgnore.getOutputRoot()).toBe("/custom/base"); + expect(antigravityCliIgnore.getFilePath()).toBe("/custom/base/.geminiignore"); + expect(antigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + + it("should handle empty content", () => { + const rulesyncIgnore = new RulesyncIgnore({ + relativeDirPath: ".rulesync", + relativeFilePath: ".rulesignore", + fileContent: "", + }); + + const antigravityCliIgnore = AntigravityCliIgnore.fromRulesyncIgnore({ + rulesyncIgnore, + }); + + expect(antigravityCliIgnore.getFileContent()).toBe(""); + }); + + it("should preserve complex patterns", () => { + const fileContent = "# Comments\n*.log\n**/*.tmp\n!important.tmp\nnode_modules/\n.env*"; + const rulesyncIgnore = new RulesyncIgnore({ + relativeDirPath: ".rulesync", + relativeFilePath: ".rulesignore", + fileContent, + }); + + const antigravityCliIgnore = AntigravityCliIgnore.fromRulesyncIgnore({ + rulesyncIgnore, + }); + + expect(antigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + }); + + describe("fromFile", () => { + it("should read .geminiignore file from outputRoot with default outputRoot", async () => { + const fileContent = "*.log\nnode_modules/\n.env"; + const ignorePath = join(testDir, ".geminiignore"); + await writeFileContent(ignorePath, fileContent); + + const antigravityCliIgnore = await AntigravityCliIgnore.fromFile({ + outputRoot: testDir, + }); + + expect(antigravityCliIgnore).toBeInstanceOf(AntigravityCliIgnore); + expect(antigravityCliIgnore.getOutputRoot()).toBe(testDir); + expect(antigravityCliIgnore.getRelativeDirPath()).toBe("."); + expect(antigravityCliIgnore.getRelativeFilePath()).toBe(".geminiignore"); + expect(antigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + + it("should read .geminiignore file with validation disabled", async () => { + const fileContent = "*.log\nnode_modules/"; + const ignorePath = join(testDir, ".geminiignore"); + await writeFileContent(ignorePath, fileContent); + + const antigravityCliIgnore = await AntigravityCliIgnore.fromFile({ + outputRoot: testDir, + validate: false, + }); + + expect(antigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + + it("should handle empty .geminiignore file", async () => { + const ignorePath = join(testDir, ".geminiignore"); + await writeFileContent(ignorePath, ""); + + const antigravityCliIgnore = await AntigravityCliIgnore.fromFile({ + outputRoot: testDir, + }); + + expect(antigravityCliIgnore.getFileContent()).toBe(""); + }); + + it("should default outputRoot to process.cwd() when not provided", async () => { + // process.cwd() is already mocked to return testDir in beforeEach + const fileContent = "*.log\nnode_modules/"; + const ignorePath = join(testDir, ".geminiignore"); + await writeFileContent(ignorePath, fileContent); + + const antigravityCliIgnore = await AntigravityCliIgnore.fromFile({}); + + expect(antigravityCliIgnore.getOutputRoot()).toBe(testDir); + expect(antigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + + it("should throw error when .geminiignore file does not exist", async () => { + await expect( + AntigravityCliIgnore.fromFile({ + outputRoot: testDir, + }), + ).rejects.toThrow(); + }); + }); + + describe("forDeletion", () => { + it("should create an instance with empty content for deletion", () => { + const antigravityCliIgnore = AntigravityCliIgnore.forDeletion({ + outputRoot: testDir, + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + }); + + expect(antigravityCliIgnore).toBeInstanceOf(AntigravityCliIgnore); + expect(antigravityCliIgnore.getFileContent()).toBe(""); + expect(antigravityCliIgnore.getFilePath()).toBe(join(testDir, ".geminiignore")); + }); + }); + + describe("inheritance from ToolIgnore", () => { + it("should inherit getPatterns method", () => { + const fileContent = "*.log\nnode_modules/\n.env"; + const antigravityCliIgnore = new AntigravityCliIgnore({ + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent, + }); + + const patterns = antigravityCliIgnore.getPatterns(); + + expect(Array.isArray(patterns)).toBe(true); + expect(patterns).toEqual(["*.log", "node_modules/", ".env"]); + }); + }); + + describe("round-trip conversion", () => { + it("should maintain content integrity in round-trip conversion", () => { + const originalContent = `# Antigravity CLI ignore patterns +*.log +node_modules/ +.env* +build/ +dist/ +*.tmp`; + + // AntigravityCliIgnore -> RulesyncIgnore -> AntigravityCliIgnore + const originalAntigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: testDir, + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent: originalContent, + }); + + const rulesyncIgnore = originalAntigravityCliIgnore.toRulesyncIgnore(); + const roundTripAntigravityCliIgnore = AntigravityCliIgnore.fromRulesyncIgnore({ + outputRoot: testDir, + rulesyncIgnore, + }); + + expect(roundTripAntigravityCliIgnore.getFileContent()).toBe(originalContent); + expect(roundTripAntigravityCliIgnore.getRelativeFilePath()).toBe(".geminiignore"); + }); + }); + + describe("file integration", () => { + it("should write and read file correctly", async () => { + const fileContent = "*.log\nnode_modules/\n.env"; + const antigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: testDir, + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + fileContent, + }); + + await writeFileContent( + antigravityCliIgnore.getFilePath(), + antigravityCliIgnore.getFileContent(), + ); + + const readAntigravityCliIgnore = await AntigravityCliIgnore.fromFile({ + outputRoot: testDir, + }); + + expect(readAntigravityCliIgnore.getFileContent()).toBe(fileContent); + expect(readAntigravityCliIgnore.getPatterns()).toEqual(["*.log", "node_modules/", ".env"]); + }); + + it("should handle subdirectory placement", async () => { + const subDir = join(testDir, "project", "config"); + await ensureDir(subDir); + + const fileContent = "*.log\nbuild/"; + const antigravityCliIgnore = new AntigravityCliIgnore({ + outputRoot: testDir, + relativeDirPath: "project/config", + relativeFilePath: ".geminiignore", + fileContent, + }); + + await writeFileContent( + antigravityCliIgnore.getFilePath(), + antigravityCliIgnore.getFileContent(), + ); + + const readAntigravityCliIgnore = await AntigravityCliIgnore.fromFile({ + outputRoot: join(testDir, "project/config"), + }); + + expect(readAntigravityCliIgnore.getFileContent()).toBe(fileContent); + }); + }); +}); diff --git a/src/features/ignore/antigravity-cli-ignore.ts b/src/features/ignore/antigravity-cli-ignore.ts new file mode 100644 index 000000000..1efb55bfc --- /dev/null +++ b/src/features/ignore/antigravity-cli-ignore.ts @@ -0,0 +1,77 @@ +import { join } from "node:path"; + +import { readFileContent } from "../../utils/file.js"; +import { RulesyncIgnore } from "./rulesync-ignore.js"; +import type { + ToolIgnoreForDeletionParams, + ToolIgnoreFromFileParams, + ToolIgnoreFromRulesyncIgnoreParams, + ToolIgnoreSettablePaths, +} from "./tool-ignore.js"; +import { ToolIgnore } from "./tool-ignore.js"; + +/** + * Antigravity CLI is the successor to Gemini CLI and is built on the same + * engine, so it reads the project-root `.geminiignore` file (same conventions as + * `.gitignore`) to exclude files and directories from the agent's context. This + * mirrors {@link GeminiCliIgnore}; the two targets emit the same file. + */ +export class AntigravityCliIgnore extends ToolIgnore { + static getSettablePaths(): ToolIgnoreSettablePaths { + return { + relativeDirPath: ".", + relativeFilePath: ".geminiignore", + }; + } + + toRulesyncIgnore(): RulesyncIgnore { + return this.toRulesyncIgnoreDefault(); + } + + static fromRulesyncIgnore({ + outputRoot = process.cwd(), + rulesyncIgnore, + }: ToolIgnoreFromRulesyncIgnoreParams): AntigravityCliIgnore { + return new AntigravityCliIgnore({ + outputRoot, + relativeDirPath: this.getSettablePaths().relativeDirPath, + relativeFilePath: this.getSettablePaths().relativeFilePath, + fileContent: rulesyncIgnore.getFileContent(), + }); + } + + static async fromFile({ + outputRoot = process.cwd(), + validate = true, + }: ToolIgnoreFromFileParams): Promise { + const fileContent = await readFileContent( + join( + outputRoot, + this.getSettablePaths().relativeDirPath, + this.getSettablePaths().relativeFilePath, + ), + ); + + return new AntigravityCliIgnore({ + outputRoot, + relativeDirPath: this.getSettablePaths().relativeDirPath, + relativeFilePath: this.getSettablePaths().relativeFilePath, + fileContent, + validate, + }); + } + + static forDeletion({ + outputRoot = process.cwd(), + relativeDirPath, + relativeFilePath, + }: ToolIgnoreForDeletionParams): AntigravityCliIgnore { + return new AntigravityCliIgnore({ + outputRoot, + relativeDirPath, + relativeFilePath, + fileContent: "", + validate: false, + }); + } +} diff --git a/src/features/ignore/ignore-processor.test.ts b/src/features/ignore/ignore-processor.test.ts index f01d8a70c..d2eb081af 100644 --- a/src/features/ignore/ignore-processor.test.ts +++ b/src/features/ignore/ignore-processor.test.ts @@ -428,6 +428,7 @@ describe("IgnoreProcessor", () => { it("should return all supported tool targets", () => { const toolTargets = IgnoreProcessor.getToolTargets(); const expectedTargets = [ + "antigravity-cli", "augmentcode", "claudecode", "claudecode-legacy", diff --git a/src/features/ignore/ignore-processor.ts b/src/features/ignore/ignore-processor.ts index 661ff08dc..d72230d26 100644 --- a/src/features/ignore/ignore-processor.ts +++ b/src/features/ignore/ignore-processor.ts @@ -8,6 +8,7 @@ import { ToolFile } from "../../types/tool-file.js"; import { ToolTarget } from "../../types/tool-targets.js"; import { formatError } from "../../utils/error.js"; import type { Logger } from "../../utils/logger.js"; +import { AntigravityCliIgnore } from "./antigravity-cli-ignore.js"; import { AugmentcodeIgnore } from "./augmentcode-ignore.js"; import { ClaudecodeIgnore } from "./claudecode-ignore.js"; import { ClineIgnore } from "./cline-ignore.js"; @@ -32,6 +33,7 @@ import { import { ZedIgnore } from "./zed-ignore.js"; const ignoreProcessorToolTargets: ToolTarget[] = [ + "antigravity-cli", "augmentcode", "claudecode", "claudecode-legacy", @@ -64,6 +66,7 @@ type ToolIgnoreFactory = { }; const toolIgnoreFactories = new Map([ + ["antigravity-cli", { class: AntigravityCliIgnore }], ["augmentcode", { class: AugmentcodeIgnore }], ["claudecode", { class: ClaudecodeIgnore }], ["claudecode-legacy", { class: ClaudecodeIgnore }],