mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
prompt refactor
This commit is contained in:
parent
775c321e7f
commit
743278c652
4 changed files with 243 additions and 133 deletions
|
|
@ -0,0 +1,93 @@
|
|||
import { describe, it, expect } from "vitest"
|
||||
import {
|
||||
generateRulesInstructions,
|
||||
ruleTypeDefinitions,
|
||||
RulesGenerationOptions,
|
||||
RuleInstruction,
|
||||
} from "../generate-rules"
|
||||
|
||||
describe("generateRulesInstructions", () => {
|
||||
it("should generate instructions with all options enabled", () => {
|
||||
const ruleInstructions: RuleInstruction[] = [ruleTypeDefinitions.general, ruleTypeDefinitions.code]
|
||||
|
||||
const options: RulesGenerationOptions = {
|
||||
selectedRuleTypes: ["general", "code"],
|
||||
addToGitignore: true,
|
||||
alwaysAllowWriteProtected: true,
|
||||
includeCustomRules: true,
|
||||
customRulesText: "Always use TypeScript",
|
||||
}
|
||||
|
||||
const result = generateRulesInstructions(ruleInstructions, options)
|
||||
|
||||
expect(result).toContain("Analyze this codebase and generate comprehensive rules")
|
||||
expect(result).toContain("coding-standards.md")
|
||||
expect(result).toContain("implementation-rules.md")
|
||||
expect(result).toContain("The directory has already been created for you")
|
||||
expect(result).toContain("Add the generated files to .gitignore")
|
||||
expect(result).toContain("Always use TypeScript")
|
||||
})
|
||||
|
||||
it("should generate instructions with minimal options", () => {
|
||||
const ruleInstructions: RuleInstruction[] = [ruleTypeDefinitions.general]
|
||||
|
||||
const options: RulesGenerationOptions = {
|
||||
selectedRuleTypes: ["general"],
|
||||
addToGitignore: false,
|
||||
alwaysAllowWriteProtected: false,
|
||||
includeCustomRules: false,
|
||||
customRulesText: "",
|
||||
}
|
||||
|
||||
const result = generateRulesInstructions(ruleInstructions, options)
|
||||
|
||||
expect(result).toContain("Analyze this codebase and generate comprehensive rules")
|
||||
expect(result).toContain("coding-standards.md")
|
||||
expect(result).toContain("Create the necessary directories if they don't exist")
|
||||
expect(result).not.toContain("Add the generated files to .gitignore")
|
||||
expect(result).not.toContain("Additional rules from User")
|
||||
})
|
||||
|
||||
it("should handle all rule types", () => {
|
||||
const allRuleTypes = Object.keys(ruleTypeDefinitions)
|
||||
const ruleInstructions: RuleInstruction[] = allRuleTypes.map(
|
||||
(type) => ruleTypeDefinitions[type as keyof typeof ruleTypeDefinitions],
|
||||
)
|
||||
|
||||
const options: RulesGenerationOptions = {
|
||||
selectedRuleTypes: allRuleTypes,
|
||||
addToGitignore: false,
|
||||
alwaysAllowWriteProtected: false,
|
||||
includeCustomRules: false,
|
||||
customRulesText: "",
|
||||
}
|
||||
|
||||
const result = generateRulesInstructions(ruleInstructions, options)
|
||||
|
||||
expect(result).toContain("coding-standards.md")
|
||||
expect(result).toContain("implementation-rules.md")
|
||||
expect(result).toContain("architecture-rules.md")
|
||||
expect(result).toContain("debugging-rules.md")
|
||||
expect(result).toContain("documentation-rules.md")
|
||||
})
|
||||
})
|
||||
|
||||
describe("ruleTypeDefinitions", () => {
|
||||
it("should have all expected rule types", () => {
|
||||
expect(ruleTypeDefinitions).toHaveProperty("general")
|
||||
expect(ruleTypeDefinitions).toHaveProperty("code")
|
||||
expect(ruleTypeDefinitions).toHaveProperty("architect")
|
||||
expect(ruleTypeDefinitions).toHaveProperty("debug")
|
||||
expect(ruleTypeDefinitions).toHaveProperty("docs-extractor")
|
||||
})
|
||||
|
||||
it("should have proper structure for each rule type", () => {
|
||||
Object.values(ruleTypeDefinitions).forEach((rule) => {
|
||||
expect(rule).toHaveProperty("path")
|
||||
expect(rule).toHaveProperty("focus")
|
||||
expect(rule).toHaveProperty("analysisSteps")
|
||||
expect(Array.isArray(rule.analysisSteps)).toBe(true)
|
||||
expect(rule.analysisSteps.length).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
127
src/core/prompts/instructions/generate-rules.ts
Normal file
127
src/core/prompts/instructions/generate-rules.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
export interface RuleInstruction {
|
||||
path: string
|
||||
focus: string
|
||||
analysisSteps: string[]
|
||||
}
|
||||
|
||||
export interface RulesGenerationOptions {
|
||||
selectedRuleTypes: string[]
|
||||
addToGitignore: boolean
|
||||
alwaysAllowWriteProtected: boolean
|
||||
includeCustomRules: boolean
|
||||
customRulesText: string
|
||||
}
|
||||
|
||||
export function generateRulesInstructions(
|
||||
ruleInstructions: RuleInstruction[],
|
||||
options: RulesGenerationOptions,
|
||||
): string {
|
||||
const { addToGitignore, alwaysAllowWriteProtected, includeCustomRules, customRulesText } = options
|
||||
|
||||
return `Analyze this codebase and generate comprehensive rules for AI agents working in this repository.
|
||||
|
||||
Your task is to:
|
||||
|
||||
1. **Analyze the project structure** by:
|
||||
${ruleInstructions.map((rule) => ` - For ${rule.path.split("/").pop()}: ${rule.analysisSteps.join("; ")}`).join("\n")}
|
||||
|
||||
2. **Look for existing rule files** that might provide guidance:
|
||||
- Check for CLAUDE.md, .cursorrules, .cursor/rules, or .github/copilot-instructions.md
|
||||
- If found, incorporate and improve upon their content
|
||||
|
||||
3. **Generate and save the following rule files**:
|
||||
${ruleInstructions
|
||||
.map(
|
||||
(rule, index) => `
|
||||
${index + 1}. **${rule.path}**
|
||||
- Focus: ${rule.focus}${alwaysAllowWriteProtected ? "\n - The directory has already been created for you" : "\n - Create the necessary directories if they don't exist"}
|
||||
- Always overwrite the existing file if it exists
|
||||
- Use the \`write_to_file\` tool to save the content${alwaysAllowWriteProtected ? "\n - Note: Auto-approval for protected file writes is enabled, so you can write to .roo directories without manual approval" : "\n - Note: You will need to approve the creation of protected directories and files"}`,
|
||||
)
|
||||
.join("\n")}
|
||||
|
||||
4. **Make the rules actionable and specific** by including:
|
||||
- Build/lint/test commands (especially for running single tests)
|
||||
- Code style guidelines including imports, formatting, types, naming conventions
|
||||
- Error handling patterns specific to this project
|
||||
- Project-specific conventions and best practices
|
||||
- File organization patterns
|
||||
|
||||
5. **Keep rules concise** - aim for 20 lines per file, focusing on the most important guidelines
|
||||
|
||||
6. **Open the generated files** in the editor for review after creation
|
||||
|
||||
${
|
||||
addToGitignore
|
||||
? `7. **Add the generated files to .gitignore**:
|
||||
- After generating all rule files, add entries to .gitignore to prevent them from being committed
|
||||
- Add each generated file path to .gitignore (e.g., .roo/rules/coding-standards.md)
|
||||
- If .gitignore doesn't exist, create it
|
||||
- If the entries already exist in .gitignore, don't duplicate them`
|
||||
: ""
|
||||
}
|
||||
|
||||
${
|
||||
includeCustomRules && customRulesText
|
||||
? `\n**Additional rules from User to add to the rules file:**\n${customRulesText}`
|
||||
: ""
|
||||
}`
|
||||
}
|
||||
|
||||
export const ruleTypeDefinitions = {
|
||||
general: {
|
||||
path: ".roo/rules/coding-standards.md",
|
||||
focus: "General coding standards that apply to all modes, including naming conventions, file organization, and general best practices",
|
||||
analysisSteps: [
|
||||
"Examine the project structure and file organization patterns",
|
||||
"Identify naming conventions for files, functions, variables, and classes",
|
||||
"Look for general coding patterns and conventions used throughout the codebase",
|
||||
"Check for any existing documentation or README files that describe project standards",
|
||||
],
|
||||
},
|
||||
code: {
|
||||
path: ".roo/rules-code/implementation-rules.md",
|
||||
focus: "Specific rules for code implementation, focusing on syntax patterns, code structure, error handling, testing approaches, and detailed implementation guidelines",
|
||||
analysisSteps: [
|
||||
"Analyze package.json or equivalent files to identify dependencies and build tools",
|
||||
"Check for linting and formatting tools (ESLint, Prettier, etc.) and their configurations",
|
||||
"Examine test files to understand testing patterns and frameworks used",
|
||||
"Look for error handling patterns and logging strategies",
|
||||
"Identify code style preferences and import/export patterns",
|
||||
"Check for TypeScript usage and type definition patterns if applicable",
|
||||
],
|
||||
},
|
||||
architect: {
|
||||
path: ".roo/rules-architect/architecture-rules.md",
|
||||
focus: "High-level system design rules, focusing on file layout, module organization, architectural patterns, and system-wide design principles",
|
||||
analysisSteps: [
|
||||
"Analyze the overall directory structure and module organization",
|
||||
"Identify architectural patterns (MVC, microservices, monorepo, etc.)",
|
||||
"Look for separation of concerns and layering patterns",
|
||||
"Check for API design patterns and service boundaries",
|
||||
"Examine how different parts of the system communicate",
|
||||
],
|
||||
},
|
||||
debug: {
|
||||
path: ".roo/rules-debug/debugging-rules.md",
|
||||
focus: "Debugging workflow rules, including error investigation approaches, logging strategies, troubleshooting patterns, and debugging best practices",
|
||||
analysisSteps: [
|
||||
"Identify logging frameworks and patterns used in the codebase",
|
||||
"Look for error handling and exception patterns",
|
||||
"Check for debugging tools or scripts in the project",
|
||||
"Analyze test structure for debugging approaches",
|
||||
"Look for monitoring or observability patterns",
|
||||
],
|
||||
},
|
||||
"docs-extractor": {
|
||||
path: ".roo/rules-docs-extractor/documentation-rules.md",
|
||||
focus: "Documentation extraction and formatting rules, including documentation style guides, API documentation patterns, and content organization",
|
||||
analysisSteps: [
|
||||
"Check for existing documentation files and their formats",
|
||||
"Analyze code comments and documentation patterns",
|
||||
"Look for API documentation tools or generators",
|
||||
"Identify documentation structure and organization patterns",
|
||||
"Check for examples or tutorials in the codebase",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import * as fs from "fs/promises"
|
||||
import * as path from "path"
|
||||
import {
|
||||
generateRulesInstructions,
|
||||
ruleTypeDefinitions,
|
||||
RulesGenerationOptions,
|
||||
RuleInstruction,
|
||||
} from "../../core/prompts/instructions/generate-rules"
|
||||
|
||||
/**
|
||||
* Creates a comprehensive task message for rules generation that can be used with initClineWithTask
|
||||
|
|
@ -32,132 +38,20 @@ export async function createRulesGenerationTaskMessage(
|
|||
}
|
||||
|
||||
// Create rule-specific instructions based on selected types
|
||||
interface RuleInstruction {
|
||||
path: string
|
||||
focus: string
|
||||
analysisSteps: string[]
|
||||
}
|
||||
|
||||
const ruleInstructions: RuleInstruction[] = selectedRuleTypes
|
||||
.map((type) => {
|
||||
switch (type) {
|
||||
case "general":
|
||||
return {
|
||||
path: ".roo/rules/coding-standards.md",
|
||||
focus: "General coding standards that apply to all modes, including naming conventions, file organization, and general best practices",
|
||||
analysisSteps: [
|
||||
"Examine the project structure and file organization patterns",
|
||||
"Identify naming conventions for files, functions, variables, and classes",
|
||||
"Look for general coding patterns and conventions used throughout the codebase",
|
||||
"Check for any existing documentation or README files that describe project standards",
|
||||
],
|
||||
}
|
||||
case "code":
|
||||
return {
|
||||
path: ".roo/rules-code/implementation-rules.md",
|
||||
focus: "Specific rules for code implementation, focusing on syntax patterns, code structure, error handling, testing approaches, and detailed implementation guidelines",
|
||||
analysisSteps: [
|
||||
"Analyze package.json or equivalent files to identify dependencies and build tools",
|
||||
"Check for linting and formatting tools (ESLint, Prettier, etc.) and their configurations",
|
||||
"Examine test files to understand testing patterns and frameworks used",
|
||||
"Look for error handling patterns and logging strategies",
|
||||
"Identify code style preferences and import/export patterns",
|
||||
"Check for TypeScript usage and type definition patterns if applicable",
|
||||
],
|
||||
}
|
||||
case "architect":
|
||||
return {
|
||||
path: ".roo/rules-architect/architecture-rules.md",
|
||||
focus: "High-level system design rules, focusing on file layout, module organization, architectural patterns, and system-wide design principles",
|
||||
analysisSteps: [
|
||||
"Analyze the overall directory structure and module organization",
|
||||
"Identify architectural patterns (MVC, microservices, monorepo, etc.)",
|
||||
"Look for separation of concerns and layering patterns",
|
||||
"Check for API design patterns and service boundaries",
|
||||
"Examine how different parts of the system communicate",
|
||||
],
|
||||
}
|
||||
case "debug":
|
||||
return {
|
||||
path: ".roo/rules-debug/debugging-rules.md",
|
||||
focus: "Debugging workflow rules, including error investigation approaches, logging strategies, troubleshooting patterns, and debugging best practices",
|
||||
analysisSteps: [
|
||||
"Identify logging frameworks and patterns used in the codebase",
|
||||
"Look for error handling and exception patterns",
|
||||
"Check for debugging tools or scripts in the project",
|
||||
"Analyze test structure for debugging approaches",
|
||||
"Look for monitoring or observability patterns",
|
||||
],
|
||||
}
|
||||
case "docs-extractor":
|
||||
return {
|
||||
path: ".roo/rules-docs-extractor/documentation-rules.md",
|
||||
focus: "Documentation extraction and formatting rules, including documentation style guides, API documentation patterns, and content organization",
|
||||
analysisSteps: [
|
||||
"Check for existing documentation files and their formats",
|
||||
"Analyze code comments and documentation patterns",
|
||||
"Look for API documentation tools or generators",
|
||||
"Identify documentation structure and organization patterns",
|
||||
"Check for examples or tutorials in the codebase",
|
||||
],
|
||||
}
|
||||
default:
|
||||
return null
|
||||
}
|
||||
const definition = ruleTypeDefinitions[type as keyof typeof ruleTypeDefinitions]
|
||||
return definition || null
|
||||
})
|
||||
.filter((rule): rule is RuleInstruction => rule !== null)
|
||||
|
||||
// Create a comprehensive message for the rules generation task
|
||||
const taskMessage = `Analyze this codebase and generate comprehensive rules for AI agents working in this repository.
|
||||
const options: RulesGenerationOptions = {
|
||||
selectedRuleTypes,
|
||||
addToGitignore,
|
||||
alwaysAllowWriteProtected,
|
||||
includeCustomRules,
|
||||
customRulesText,
|
||||
}
|
||||
|
||||
Your task is to:
|
||||
|
||||
1. **Analyze the project structure** by:
|
||||
${ruleInstructions.map((rule) => ` - For ${rule.path.split("/").pop()}: ${rule.analysisSteps.join("; ")}`).join("\n")}
|
||||
|
||||
2. **Look for existing rule files** that might provide guidance:
|
||||
- Check for CLAUDE.md, .cursorrules, .cursor/rules, or .github/copilot-instructions.md
|
||||
- If found, incorporate and improve upon their content
|
||||
|
||||
3. **Generate and save the following rule files**:
|
||||
${ruleInstructions
|
||||
.map(
|
||||
(rule, index) => `
|
||||
${index + 1}. **${rule.path}**
|
||||
- Focus: ${rule.focus}${alwaysAllowWriteProtected ? "\n - The directory has already been created for you" : "\n - Create the necessary directories if they don't exist"}
|
||||
- Always overwrite the existing file if it exists
|
||||
- Use the \`write_to_file\` tool to save the content${alwaysAllowWriteProtected ? "\n - Note: Auto-approval for protected file writes is enabled, so you can write to .roo directories without manual approval" : "\n - Note: You will need to approve the creation of protected directories and files"}`,
|
||||
)
|
||||
.join("\n")}
|
||||
|
||||
4. **Make the rules actionable and specific** by including:
|
||||
- Build/lint/test commands (especially for running single tests)
|
||||
- Code style guidelines including imports, formatting, types, naming conventions
|
||||
- Error handling patterns specific to this project
|
||||
- Project-specific conventions and best practices
|
||||
- File organization patterns
|
||||
|
||||
5. **Keep rules concise** - aim for 20 lines per file, focusing on the most important guidelines
|
||||
|
||||
6. **Open the generated files** in the editor for review after creation
|
||||
|
||||
Use the \`safeWriteJson\` utility from \`src/utils/safeWriteJson.ts\` for any JSON file operations to ensure atomic writes.
|
||||
|
||||
${
|
||||
addToGitignore
|
||||
? `7. **Add the generated files to .gitignore**:
|
||||
- After generating all rule files, add entries to .gitignore to prevent them from being committed
|
||||
- Add each generated file path to .gitignore (e.g., .roo/rules/coding-standards.md)
|
||||
- If .gitignore doesn't exist, create it
|
||||
- If the entries already exist in .gitignore, don't duplicate them`
|
||||
: ""
|
||||
}
|
||||
|
||||
${
|
||||
includeCustomRules && customRulesText
|
||||
? `\n**Additional rules from User to add to the rules file:**\n${customRulesText}`
|
||||
: ""
|
||||
}`
|
||||
|
||||
return taskMessage
|
||||
return generateRulesInstructions(ruleInstructions, options)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
<Section>
|
||||
<div className="space-y-6">
|
||||
{/* Magic Rules Generation subsection */}
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center gap-2 font-bold">
|
||||
<Sparkles className="w-4 h-4" />
|
||||
|
|
@ -188,9 +188,9 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
{t("settings:rules.magicGeneration.description")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 pl-3 border-l-2 border-vscode-button-background">
|
||||
<div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
|
||||
{/* Recommendation box */}
|
||||
<div className="flex items-start gap-2 p-3 bg-vscode-inputValidation-infoBackground border border-vscode-inputValidation-infoBorder rounded-md">
|
||||
<div className="flex items-start gap-2 p-2 bg-vscode-inputValidation-infoBackground border border-vscode-inputValidation-infoBorder rounded-md">
|
||||
<Info className="w-4 h-4 text-vscode-inputValidation-infoForeground mt-0.5 flex-shrink-0" />
|
||||
<div className="text-sm text-vscode-inputValidation-infoForeground">
|
||||
{t("settings:rules.autoApproveRecommendation")}
|
||||
|
|
@ -233,7 +233,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
|
||||
{/* Small repository warning */}
|
||||
{sourceFileCount !== null && sourceFileCount > 0 && sourceFileCount < 20 && (
|
||||
<div className="flex items-start gap-2 p-3 bg-vscode-inputValidation-warningBackground border border-vscode-inputValidation-warningBorder rounded-md">
|
||||
<div className="flex items-start gap-2 p-2 bg-vscode-inputValidation-warningBackground border border-vscode-inputValidation-warningBorder rounded-md">
|
||||
<AlertTriangle className="w-4 h-4 text-vscode-inputValidation-warningForeground mt-0.5 flex-shrink-0" />
|
||||
<div className="text-sm text-vscode-inputValidation-warningForeground">
|
||||
{t("settings:rules.smallRepoWarning", { count: sourceFileCount })}
|
||||
|
|
@ -241,7 +241,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
</div>
|
||||
)}
|
||||
{hasExistingFiles && (
|
||||
<div className="flex items-start gap-2 p-3 bg-vscode-inputValidation-warningBackground border border-vscode-inputValidation-warningBorder rounded-md">
|
||||
<div className="flex items-start gap-2 p-2 bg-vscode-inputValidation-warningBackground border border-vscode-inputValidation-warningBorder rounded-md">
|
||||
<AlertTriangle className="w-4 h-4 text-vscode-inputValidation-warningForeground mt-0.5 flex-shrink-0" />
|
||||
<div className="text-sm text-vscode-inputValidation-warningForeground">
|
||||
<div>{t("settings:rules.overwriteWarning")}</div>
|
||||
|
|
@ -254,7 +254,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="border-t border-vscode-panel-border pt-2">
|
||||
<div className="border-t border-vscode-panel-border pt-2 space-y-2">
|
||||
<label className="flex items-center gap-2 cursor-pointer hover:opacity-80">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
@ -268,9 +268,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-vscode-panel-border pt-2">
|
||||
<label className="flex items-center gap-2 cursor-pointer hover:opacity-80">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
@ -292,9 +290,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-vscode-panel-border pt-4">
|
||||
<label className="flex items-center gap-2 cursor-pointer hover:opacity-80">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
@ -333,7 +329,7 @@ export const RulesSettings = ({ className, hasUnsavedChanges, ...props }: RulesS
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-2 mt-3">
|
||||
<Select value={selectedApiConfig} onValueChange={setSelectedApiConfig}>
|
||||
<SelectTrigger className="w-fit min-w-[5rem] max-w-[8rem]">
|
||||
<SelectValue placeholder={t("settings:rules.selectApiConfig")} />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue