diff --git a/src/core/prompts/sections/__tests__/custom-instructions.test.ts b/src/core/prompts/sections/__tests__/custom-instructions.test.ts index 4dbb51c845b..80762dcac3f 100644 --- a/src/core/prompts/sections/__tests__/custom-instructions.test.ts +++ b/src/core/prompts/sections/__tests__/custom-instructions.test.ts @@ -14,11 +14,7 @@ describe("loadRuleFiles", () => { mockedFs.readFile.mockResolvedValue(" content with spaces ") const result = await loadRuleFiles("/fake/path") expect(mockedFs.readFile).toHaveBeenCalled() - expect(result).toBe( - "\n# Rules from .clinerules:\ncontent with spaces\n" + - "\n# Rules from .cursorrules:\ncontent with spaces\n" + - "\n# Rules from .windsurfrules:\ncontent with spaces\n", - ) + expect(result).toBe("\n# Rules from .roorules:\ncontent with spaces\n") }) it("should handle ENOENT error", async () => { @@ -49,22 +45,19 @@ describe("loadRuleFiles", () => { jest.clearAllMocks() }) - it("should combine content from multiple rule files when they exist", async () => { + it("should not combine content from multiple rule files when they exist", async () => { mockedFs.readFile.mockImplementation(((filePath: string | Buffer | URL | number) => { + if (filePath.toString().endsWith(".roorules")) { + return Promise.resolve("roo rules content") + } if (filePath.toString().endsWith(".clinerules")) { return Promise.resolve("cline rules content") } - if (filePath.toString().endsWith(".cursorrules")) { - return Promise.resolve("cursor rules content") - } return Promise.reject({ code: "ENOENT" }) }) as any) const result = await loadRuleFiles("/fake/path") - expect(result).toBe( - "\n# Rules from .clinerules:\ncline rules content\n" + - "\n# Rules from .cursorrules:\ncursor rules content\n", - ) + expect(result).toBe("\n# Rules from .roorules:\nroo rules content\n") }) it("should handle when no rule files exist", async () => { @@ -86,17 +79,17 @@ describe("loadRuleFiles", () => { it("should skip directories with same name as rule files", async () => { mockedFs.readFile.mockImplementation(((filePath: string | Buffer | URL | number) => { - if (filePath.toString().endsWith(".clinerules")) { + if (filePath.toString().endsWith(".roorules")) { return Promise.reject({ code: "EISDIR" }) } - if (filePath.toString().endsWith(".cursorrules")) { - return Promise.resolve("cursor rules content") + if (filePath.toString().endsWith(".clinerules")) { + return Promise.reject({ code: "EISDIR" }) } return Promise.reject({ code: "ENOENT" }) }) as any) const result = await loadRuleFiles("/fake/path") - expect(result).toBe("\n# Rules from .cursorrules:\ncursor rules content\n") + expect(result).toBe("") }) }) @@ -121,7 +114,7 @@ describe("addCustomInstructions", () => { expect(result).toContain("(es)") // Check for language code in parentheses expect(result).toContain("Global Instructions:\nglobal instructions") expect(result).toContain("Mode-specific Instructions:\nmode instructions") - expect(result).toContain("Rules from .clinerules-test-mode:\nmode specific rules") + expect(result).toContain("Rules from .roorules-test-mode:\nmode specific rules") }) it("should return empty string when no instructions provided", async () => { diff --git a/src/core/prompts/sections/custom-instructions.ts b/src/core/prompts/sections/custom-instructions.ts index bf5b009bc23..f6b46764282 100644 --- a/src/core/prompts/sections/custom-instructions.ts +++ b/src/core/prompts/sections/custom-instructions.ts @@ -17,17 +17,16 @@ async function safeReadFile(filePath: string): Promise { } export async function loadRuleFiles(cwd: string): Promise { - const ruleFiles = [".clinerules", ".cursorrules", ".windsurfrules"] - let combinedRules = "" + const ruleFiles = [".roorules", ".clinerules"] for (const file of ruleFiles) { const content = await safeReadFile(path.join(cwd, file)) if (content) { - combinedRules += `\n# Rules from ${file}:\n${content}\n` + return `\n# Rules from ${file}:\n${content}\n` } } - return combinedRules + return "" } export async function addCustomInstructions( @@ -41,9 +40,19 @@ export async function addCustomInstructions( // Load mode-specific rules if mode is provided let modeRuleContent = "" + let usedRuleFile = "" if (mode) { - const modeRuleFile = `.clinerules-${mode}` - modeRuleContent = await safeReadFile(path.join(cwd, modeRuleFile)) + const rooModeRuleFile = `.roorules-${mode}` + modeRuleContent = await safeReadFile(path.join(cwd, rooModeRuleFile)) + if (modeRuleContent) { + usedRuleFile = rooModeRuleFile + } else { + const clineModeRuleFile = `.clinerules-${mode}` + modeRuleContent = await safeReadFile(path.join(cwd, clineModeRuleFile)) + if (modeRuleContent) { + usedRuleFile = clineModeRuleFile + } + } } // Add language preference if provided @@ -69,8 +78,7 @@ export async function addCustomInstructions( // Add mode-specific rules first if they exist if (modeRuleContent && modeRuleContent.trim()) { - const modeRuleFile = `.clinerules-${mode}` - rules.push(`# Rules from ${modeRuleFile}:\n${modeRuleContent}`) + rules.push(`# Rules from ${usedRuleFile}:\n${modeRuleContent}`) } if (options.rooIgnoreInstructions) { diff --git a/webview-ui/src/components/history/HistoryView.tsx b/webview-ui/src/components/history/HistoryView.tsx index a1bbdb556f2..c74d6b0d96e 100644 --- a/webview-ui/src/components/history/HistoryView.tsx +++ b/webview-ui/src/components/history/HistoryView.tsx @@ -4,12 +4,7 @@ import { BatchDeleteTaskDialog } from "./BatchDeleteTaskDialog" import prettyBytes from "pretty-bytes" import { Virtuoso } from "react-virtuoso" -import { - VSCodeTextField, - VSCodeRadioGroup, - VSCodeRadio, - VSCodeCheckbox, -} from "@vscode/webview-ui-toolkit/react" +import { VSCodeTextField, VSCodeRadioGroup, VSCodeRadio, VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react" import { vscode } from "@/utils/vscode" import { formatLargeNumber, formatDate } from "@/utils/format" diff --git a/webview-ui/src/components/prompts/PromptsView.tsx b/webview-ui/src/components/prompts/PromptsView.tsx index 15044fb2f8b..24ba4ad67c0 100644 --- a/webview-ui/src/components/prompts/PromptsView.tsx +++ b/webview-ui/src/components/prompts/PromptsView.tsx @@ -618,10 +618,10 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
{t("prompts:tools.title")}
{findModeBySlug(mode, customModes) && (