Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/core/prompts/sections/__tests__/custom-instructions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ describe("loadRuleFiles", () => {
const result = await loadRuleFiles("/fake/path")
expect(mockedFs.readFile).toHaveBeenCalled()
expect(result).toBe(
"\n# Rules from .clinerules:\ncontent with spaces\n" +
"\n# Rules from .roorules:\ncontent with spaces\n" +
"\n# Rules from .clinerules:\ncontent with spaces\n" +
"\n# Rules from .cursorrules:\ncontent with spaces\n" +
"\n# Rules from .windsurfrules:\ncontent with spaces\n",
)
Expand Down Expand Up @@ -51,6 +52,9 @@ describe("loadRuleFiles", () => {

it("should 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")
}
Expand All @@ -62,7 +66,8 @@ describe("loadRuleFiles", () => {

const result = await loadRuleFiles("/fake/path")
expect(result).toBe(
"\n# Rules from .clinerules:\ncline rules content\n" +
"\n# Rules from .roorules:\nroo rules content\n" +
"\n# Rules from .clinerules:\ncline rules content\n" +
"\n# Rules from .cursorrules:\ncursor rules content\n",
)
})
Expand All @@ -86,6 +91,9 @@ 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(".roorules")) {
return Promise.reject({ code: "EISDIR" })
}
if (filePath.toString().endsWith(".clinerules")) {
return Promise.reject({ code: "EISDIR" })
}
Expand Down Expand Up @@ -121,7 +129,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 () => {
Expand Down
19 changes: 14 additions & 5 deletions src/core/prompts/sections/custom-instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function safeReadFile(filePath: string): Promise<string> {
}

export async function loadRuleFiles(cwd: string): Promise<string> {
const ruleFiles = [".clinerules", ".cursorrules", ".windsurfrules"]
const ruleFiles = [".roorules", ".clinerules", ".cursorrules", ".windsurfrules"]
let combinedRules = ""

for (const file of ruleFiles) {
Expand All @@ -41,9 +41,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
Expand All @@ -69,8 +79,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) {
Expand Down