From d577ec4ba12eb087109dad498dee788c8d4dc1fc Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:02:02 -0800 Subject: [PATCH] Add .clinerules --- src/core/Cline.ts | 20 +++++++++++++++++--- src/core/prompts/system.ts | 10 +++++++++- src/core/webview/ClineProvider.ts | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 9c2187e20c..d564ac489a 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -46,7 +46,7 @@ import { AssistantMessageContent, parseAssistantMessage, ToolParamName, ToolUseN import { constructNewFileContent } from "./assistant-message/diff" import { parseMentions } from "./mentions" import { formatResponse } from "./prompts/responses" -import { addCustomInstructions, SYSTEM_PROMPT } from "./prompts/system" +import { addUserInstructions, SYSTEM_PROMPT } from "./prompts/system" import { truncateHalfConversation } from "./sliding-window" import { ClineProvider, GlobalFileNames } from "./webview/ClineProvider" import { showSystemNotification } from "../integrations/notifications" @@ -788,9 +788,23 @@ export class Cline { } let systemPrompt = await SYSTEM_PROMPT(cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub) - if (this.customInstructions && this.customInstructions.trim()) { + let settingsCustomInstructions = this.customInstructions?.trim() + const clineRulesFilePath = path.resolve(cwd, GlobalFileNames.clineRules) + let clineRulesFileInstructions: string | undefined + if (await fileExistsAtPath(clineRulesFilePath)) { + try { + const ruleFileContent = (await fs.readFile(clineRulesFilePath, "utf8")).trim() + if (ruleFileContent) { + clineRulesFileInstructions = `# .clinerules\n\nThe following instructions are provided by a root-level .clinerules file where the user has specified instructions for this working directory (${cwd.toPosix()})\n\n${ruleFileContent}` + } + } catch { + console.error(`Failed to read .clinerules file at ${clineRulesFilePath}`) + } + } + + if (settingsCustomInstructions || clineRulesFileInstructions) { // altering the system prompt mid-task will break the prompt cache, but in the grand scheme this will not change often so it's better to not pollute user messages with it the way we have to with - systemPrompt += addCustomInstructions(this.customInstructions) + systemPrompt += addUserInstructions(settingsCustomInstructions, clineRulesFileInstructions) } // If the previous API request's total token usage is close to the context window, truncate the conversation history to free up space for the new request diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index 8329883d1a..2010aceb01 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -871,7 +871,15 @@ You accomplish a given task iteratively, breaking it down into clear steps and w 4. Once you've completed the user's task, you must use the attempt_completion tool to present the result of the task to the user. You may also provide a CLI command to showcase the result of your task; this can be particularly useful for web development tasks, where you can run e.g. \`open index.html\` to show the website you've built. 5. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.` -export function addCustomInstructions(customInstructions: string): string { +export function addUserInstructions(settingsCustomInstructions?: string, clineRulesFileInstructions?: string) { + let customInstructions = "" + if (settingsCustomInstructions) { + customInstructions += settingsCustomInstructions + "\n\n" + } + if (clineRulesFileInstructions) { + customInstructions += clineRulesFileInstructions + } + return ` ==== diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index b3e7f765ef..8a556f9369 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -66,6 +66,7 @@ export const GlobalFileNames = { uiMessages: "ui_messages.json", openRouterModels: "openrouter_models.json", mcpSettings: "cline_mcp_settings.json", + clineRules: ".clinerules", } export class ClineProvider implements vscode.WebviewViewProvider {