Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
65 changes: 37 additions & 28 deletions core/config/markdown/loadMarkdownRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<{
Expand Down Expand Up @@ -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 };
Expand Down
21 changes: 15 additions & 6 deletions core/promptFiles/getPromptFiles.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions core/promptFiles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading