diff --git a/core/config/markdown/loadMarkdownRules.ts b/core/config/markdown/loadMarkdownRules.ts index 4a2cd4051bb..bdeddedaaae 100644 --- a/core/config/markdown/loadMarkdownRules.ts +++ b/core/config/markdown/loadMarkdownRules.ts @@ -3,12 +3,13 @@ import { markdownToRule, } from "@continuedev/config-yaml"; import { IDE, RuleWithSource } from "../.."; +import { PROMPTS_DIR_NAME, RULES_DIR_NAME } from "../../promptFiles"; import { joinPathsToUri } from "../../util/uri"; import { getAllDotContinueDefinitionFiles } from "../loadLocalAssistants"; export const SUPPORTED_AGENT_FILES = ["AGENTS.md", "AGENT.md", "CLAUDE.md"]; /** - * Loads rules from markdown files in the .continue/rules directory + * Loads rules from markdown files in the .continue/rules and .continue/prompts directories * and agent files (AGENTS.md, AGENT.md, CLAUDE.md) at workspace root */ export async function loadMarkdownRules(ide: IDE): Promise<{ @@ -53,37 +54,45 @@ export async function loadMarkdownRules(ide: IDE): Promise<{ } } - try { - // Get all .md files from .continue/rules - const markdownFiles = await getAllDotContinueDefinitionFiles( - ide, - { includeGlobal: true, includeWorkspace: true, fileExtType: "markdown" }, - "rules", - ); + // Load markdown files from both .continue/rules and .continue/prompts + const dirsToCheck = [RULES_DIR_NAME, PROMPTS_DIR_NAME]; - // Filter to just .md files - const mdFiles = markdownFiles.filter((file) => file.path.endsWith(".md")); + for (const dirName of dirsToCheck) { + try { + const markdownFiles = await getAllDotContinueDefinitionFiles( + ide, + { + includeGlobal: true, + includeWorkspace: true, + fileExtType: "markdown", + }, + dirName, + ); - // Process each markdown file - for (const file of mdFiles) { - try { - const rule = markdownToRule(file.content, { - uriType: "file", - fileUri: file.path, - }); - rules.push({ ...rule, source: "rules-block", sourceFile: file.path }); - } catch (e) { - errors.push({ - fatal: false, - message: `Failed to parse markdown rule file ${file.path}: ${e instanceof Error ? e.message : e}`, - }); + // Filter to just .md files + const mdFiles = markdownFiles.filter((file) => file.path.endsWith(".md")); + + // Process each markdown file + for (const file of mdFiles) { + try { + const rule = markdownToRule(file.content, { + uriType: "file", + fileUri: file.path, + }); + rules.push({ ...rule, source: "rules-block", sourceFile: file.path }); + } catch (e) { + errors.push({ + fatal: false, + message: `Failed to parse markdown rule file ${file.path}: ${e instanceof Error ? e.message : e}`, + }); + } } + } catch (e) { + errors.push({ + fatal: false, + message: `Error loading markdown rule files from ${dirName}: ${e instanceof Error ? e.message : e}`, + }); } - } catch (e) { - errors.push({ - fatal: false, - message: `Error loading markdown rule files: ${e instanceof Error ? e.message : e}`, - }); } return { rules, errors }; diff --git a/core/promptFiles/getPromptFiles.ts b/core/promptFiles/getPromptFiles.ts index 59c0151d456..6a3837e3ab6 100644 --- a/core/promptFiles/getPromptFiles.ts +++ b/core/promptFiles/getPromptFiles.ts @@ -1,11 +1,15 @@ -import { DEFAULT_PROMPTS_FOLDER_V1 } from "."; +import path from "path"; +import { + DEFAULT_PROMPTS_FOLDER_V1, + DEFAULT_PROMPTS_FOLDER_V2, + DEFAULT_RULES_FOLDER, + RULES_DIR_NAME, +} from "."; import { IDE } from ".."; import { walkDir } from "../indexing/walkDir"; -import { readAllGlobalPromptFiles } from "../util/paths"; +import { getContinueGlobalPath, readAllGlobalPromptFiles } from "../util/paths"; import { joinPathsToUri } from "../util/uri"; -export const DEFAULT_PROMPTS_FOLDER_V2 = ".continue/prompts"; - export async function getPromptFilesFromDir( ide: IDE, dir: string, @@ -40,7 +44,7 @@ export async function getAllPromptFiles( const workspaceDirs = await ide.getWorkspaceDirs(); let promptFiles: { path: string; content: string }[] = []; - let dirsToCheck = [DEFAULT_PROMPTS_FOLDER_V2]; + let dirsToCheck = [DEFAULT_PROMPTS_FOLDER_V2, DEFAULT_RULES_FOLDER]; if (checkV1DefaultFolder) { dirsToCheck.push(DEFAULT_PROMPTS_FOLDER_V1); } @@ -56,9 +60,14 @@ export async function getAllPromptFiles( await Promise.all(fullDirs.map((dir) => getPromptFilesFromDir(ide, dir))) ).flat(); - // Also read from ~/.continue/prompts + // Also read from ~/.continue/prompts and ~/.continue/rules promptFiles.push(...readAllGlobalPromptFiles()); + const promptFilesFromRulesDirectory = readAllGlobalPromptFiles( + path.join(getContinueGlobalPath(), RULES_DIR_NAME), + ); + promptFiles.push(...promptFilesFromRulesDirectory); + return await Promise.all( promptFiles.map(async (file) => { const content = await ide.readFile(file.path); diff --git a/core/promptFiles/index.ts b/core/promptFiles/index.ts index ee5fb6b845b..58be45fe835 100644 --- a/core/promptFiles/index.ts +++ b/core/promptFiles/index.ts @@ -2,6 +2,11 @@ import { ContextProviderName } from ".."; export const DEFAULT_PROMPTS_FOLDER_V1 = ".prompts"; export const DEFAULT_PROMPTS_FOLDER_V2 = ".continue/prompts"; +export const DEFAULT_RULES_FOLDER = ".continue/rules"; + +// Subdirectory names (without .continue/ prefix) +export const RULES_DIR_NAME = "rules"; +export const PROMPTS_DIR_NAME = "prompts"; export const SUPPORTED_PROMPT_CONTEXT_PROVIDERS: ContextProviderName[] = [ "file",