Skip to content

Commit 743278c

Browse files
committed
prompt refactor
1 parent 775c321 commit 743278c

File tree

4 files changed

+243
-133
lines changed

4 files changed

+243
-133
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { describe, it, expect } from "vitest"
2+
import {
3+
generateRulesInstructions,
4+
ruleTypeDefinitions,
5+
RulesGenerationOptions,
6+
RuleInstruction,
7+
} from "../generate-rules"
8+
9+
describe("generateRulesInstructions", () => {
10+
it("should generate instructions with all options enabled", () => {
11+
const ruleInstructions: RuleInstruction[] = [ruleTypeDefinitions.general, ruleTypeDefinitions.code]
12+
13+
const options: RulesGenerationOptions = {
14+
selectedRuleTypes: ["general", "code"],
15+
addToGitignore: true,
16+
alwaysAllowWriteProtected: true,
17+
includeCustomRules: true,
18+
customRulesText: "Always use TypeScript",
19+
}
20+
21+
const result = generateRulesInstructions(ruleInstructions, options)
22+
23+
expect(result).toContain("Analyze this codebase and generate comprehensive rules")
24+
expect(result).toContain("coding-standards.md")
25+
expect(result).toContain("implementation-rules.md")
26+
expect(result).toContain("The directory has already been created for you")
27+
expect(result).toContain("Add the generated files to .gitignore")
28+
expect(result).toContain("Always use TypeScript")
29+
})
30+
31+
it("should generate instructions with minimal options", () => {
32+
const ruleInstructions: RuleInstruction[] = [ruleTypeDefinitions.general]
33+
34+
const options: RulesGenerationOptions = {
35+
selectedRuleTypes: ["general"],
36+
addToGitignore: false,
37+
alwaysAllowWriteProtected: false,
38+
includeCustomRules: false,
39+
customRulesText: "",
40+
}
41+
42+
const result = generateRulesInstructions(ruleInstructions, options)
43+
44+
expect(result).toContain("Analyze this codebase and generate comprehensive rules")
45+
expect(result).toContain("coding-standards.md")
46+
expect(result).toContain("Create the necessary directories if they don't exist")
47+
expect(result).not.toContain("Add the generated files to .gitignore")
48+
expect(result).not.toContain("Additional rules from User")
49+
})
50+
51+
it("should handle all rule types", () => {
52+
const allRuleTypes = Object.keys(ruleTypeDefinitions)
53+
const ruleInstructions: RuleInstruction[] = allRuleTypes.map(
54+
(type) => ruleTypeDefinitions[type as keyof typeof ruleTypeDefinitions],
55+
)
56+
57+
const options: RulesGenerationOptions = {
58+
selectedRuleTypes: allRuleTypes,
59+
addToGitignore: false,
60+
alwaysAllowWriteProtected: false,
61+
includeCustomRules: false,
62+
customRulesText: "",
63+
}
64+
65+
const result = generateRulesInstructions(ruleInstructions, options)
66+
67+
expect(result).toContain("coding-standards.md")
68+
expect(result).toContain("implementation-rules.md")
69+
expect(result).toContain("architecture-rules.md")
70+
expect(result).toContain("debugging-rules.md")
71+
expect(result).toContain("documentation-rules.md")
72+
})
73+
})
74+
75+
describe("ruleTypeDefinitions", () => {
76+
it("should have all expected rule types", () => {
77+
expect(ruleTypeDefinitions).toHaveProperty("general")
78+
expect(ruleTypeDefinitions).toHaveProperty("code")
79+
expect(ruleTypeDefinitions).toHaveProperty("architect")
80+
expect(ruleTypeDefinitions).toHaveProperty("debug")
81+
expect(ruleTypeDefinitions).toHaveProperty("docs-extractor")
82+
})
83+
84+
it("should have proper structure for each rule type", () => {
85+
Object.values(ruleTypeDefinitions).forEach((rule) => {
86+
expect(rule).toHaveProperty("path")
87+
expect(rule).toHaveProperty("focus")
88+
expect(rule).toHaveProperty("analysisSteps")
89+
expect(Array.isArray(rule.analysisSteps)).toBe(true)
90+
expect(rule.analysisSteps.length).toBeGreaterThan(0)
91+
})
92+
})
93+
})
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
export interface RuleInstruction {
2+
path: string
3+
focus: string
4+
analysisSteps: string[]
5+
}
6+
7+
export interface RulesGenerationOptions {
8+
selectedRuleTypes: string[]
9+
addToGitignore: boolean
10+
alwaysAllowWriteProtected: boolean
11+
includeCustomRules: boolean
12+
customRulesText: string
13+
}
14+
15+
export function generateRulesInstructions(
16+
ruleInstructions: RuleInstruction[],
17+
options: RulesGenerationOptions,
18+
): string {
19+
const { addToGitignore, alwaysAllowWriteProtected, includeCustomRules, customRulesText } = options
20+
21+
return `Analyze this codebase and generate comprehensive rules for AI agents working in this repository.
22+
23+
Your task is to:
24+
25+
1. **Analyze the project structure** by:
26+
${ruleInstructions.map((rule) => ` - For ${rule.path.split("/").pop()}: ${rule.analysisSteps.join("; ")}`).join("\n")}
27+
28+
2. **Look for existing rule files** that might provide guidance:
29+
- Check for CLAUDE.md, .cursorrules, .cursor/rules, or .github/copilot-instructions.md
30+
- If found, incorporate and improve upon their content
31+
32+
3. **Generate and save the following rule files**:
33+
${ruleInstructions
34+
.map(
35+
(rule, index) => `
36+
${index + 1}. **${rule.path}**
37+
- Focus: ${rule.focus}${alwaysAllowWriteProtected ? "\n - The directory has already been created for you" : "\n - Create the necessary directories if they don't exist"}
38+
- Always overwrite the existing file if it exists
39+
- 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"}`,
40+
)
41+
.join("\n")}
42+
43+
4. **Make the rules actionable and specific** by including:
44+
- Build/lint/test commands (especially for running single tests)
45+
- Code style guidelines including imports, formatting, types, naming conventions
46+
- Error handling patterns specific to this project
47+
- Project-specific conventions and best practices
48+
- File organization patterns
49+
50+
5. **Keep rules concise** - aim for 20 lines per file, focusing on the most important guidelines
51+
52+
6. **Open the generated files** in the editor for review after creation
53+
54+
${
55+
addToGitignore
56+
? `7. **Add the generated files to .gitignore**:
57+
- After generating all rule files, add entries to .gitignore to prevent them from being committed
58+
- Add each generated file path to .gitignore (e.g., .roo/rules/coding-standards.md)
59+
- If .gitignore doesn't exist, create it
60+
- If the entries already exist in .gitignore, don't duplicate them`
61+
: ""
62+
}
63+
64+
${
65+
includeCustomRules && customRulesText
66+
? `\n**Additional rules from User to add to the rules file:**\n${customRulesText}`
67+
: ""
68+
}`
69+
}
70+
71+
export const ruleTypeDefinitions = {
72+
general: {
73+
path: ".roo/rules/coding-standards.md",
74+
focus: "General coding standards that apply to all modes, including naming conventions, file organization, and general best practices",
75+
analysisSteps: [
76+
"Examine the project structure and file organization patterns",
77+
"Identify naming conventions for files, functions, variables, and classes",
78+
"Look for general coding patterns and conventions used throughout the codebase",
79+
"Check for any existing documentation or README files that describe project standards",
80+
],
81+
},
82+
code: {
83+
path: ".roo/rules-code/implementation-rules.md",
84+
focus: "Specific rules for code implementation, focusing on syntax patterns, code structure, error handling, testing approaches, and detailed implementation guidelines",
85+
analysisSteps: [
86+
"Analyze package.json or equivalent files to identify dependencies and build tools",
87+
"Check for linting and formatting tools (ESLint, Prettier, etc.) and their configurations",
88+
"Examine test files to understand testing patterns and frameworks used",
89+
"Look for error handling patterns and logging strategies",
90+
"Identify code style preferences and import/export patterns",
91+
"Check for TypeScript usage and type definition patterns if applicable",
92+
],
93+
},
94+
architect: {
95+
path: ".roo/rules-architect/architecture-rules.md",
96+
focus: "High-level system design rules, focusing on file layout, module organization, architectural patterns, and system-wide design principles",
97+
analysisSteps: [
98+
"Analyze the overall directory structure and module organization",
99+
"Identify architectural patterns (MVC, microservices, monorepo, etc.)",
100+
"Look for separation of concerns and layering patterns",
101+
"Check for API design patterns and service boundaries",
102+
"Examine how different parts of the system communicate",
103+
],
104+
},
105+
debug: {
106+
path: ".roo/rules-debug/debugging-rules.md",
107+
focus: "Debugging workflow rules, including error investigation approaches, logging strategies, troubleshooting patterns, and debugging best practices",
108+
analysisSteps: [
109+
"Identify logging frameworks and patterns used in the codebase",
110+
"Look for error handling and exception patterns",
111+
"Check for debugging tools or scripts in the project",
112+
"Analyze test structure for debugging approaches",
113+
"Look for monitoring or observability patterns",
114+
],
115+
},
116+
"docs-extractor": {
117+
path: ".roo/rules-docs-extractor/documentation-rules.md",
118+
focus: "Documentation extraction and formatting rules, including documentation style guides, API documentation patterns, and content organization",
119+
analysisSteps: [
120+
"Check for existing documentation files and their formats",
121+
"Analyze code comments and documentation patterns",
122+
"Look for API documentation tools or generators",
123+
"Identify documentation structure and organization patterns",
124+
"Check for examples or tutorials in the codebase",
125+
],
126+
},
127+
}
Lines changed: 16 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import * as fs from "fs/promises"
22
import * as path from "path"
3+
import {
4+
generateRulesInstructions,
5+
ruleTypeDefinitions,
6+
RulesGenerationOptions,
7+
RuleInstruction,
8+
} from "../../core/prompts/instructions/generate-rules"
39

410
/**
511
* Creates a comprehensive task message for rules generation that can be used with initClineWithTask
@@ -32,132 +38,20 @@ export async function createRulesGenerationTaskMessage(
3238
}
3339

3440
// Create rule-specific instructions based on selected types
35-
interface RuleInstruction {
36-
path: string
37-
focus: string
38-
analysisSteps: string[]
39-
}
40-
4141
const ruleInstructions: RuleInstruction[] = selectedRuleTypes
4242
.map((type) => {
43-
switch (type) {
44-
case "general":
45-
return {
46-
path: ".roo/rules/coding-standards.md",
47-
focus: "General coding standards that apply to all modes, including naming conventions, file organization, and general best practices",
48-
analysisSteps: [
49-
"Examine the project structure and file organization patterns",
50-
"Identify naming conventions for files, functions, variables, and classes",
51-
"Look for general coding patterns and conventions used throughout the codebase",
52-
"Check for any existing documentation or README files that describe project standards",
53-
],
54-
}
55-
case "code":
56-
return {
57-
path: ".roo/rules-code/implementation-rules.md",
58-
focus: "Specific rules for code implementation, focusing on syntax patterns, code structure, error handling, testing approaches, and detailed implementation guidelines",
59-
analysisSteps: [
60-
"Analyze package.json or equivalent files to identify dependencies and build tools",
61-
"Check for linting and formatting tools (ESLint, Prettier, etc.) and their configurations",
62-
"Examine test files to understand testing patterns and frameworks used",
63-
"Look for error handling patterns and logging strategies",
64-
"Identify code style preferences and import/export patterns",
65-
"Check for TypeScript usage and type definition patterns if applicable",
66-
],
67-
}
68-
case "architect":
69-
return {
70-
path: ".roo/rules-architect/architecture-rules.md",
71-
focus: "High-level system design rules, focusing on file layout, module organization, architectural patterns, and system-wide design principles",
72-
analysisSteps: [
73-
"Analyze the overall directory structure and module organization",
74-
"Identify architectural patterns (MVC, microservices, monorepo, etc.)",
75-
"Look for separation of concerns and layering patterns",
76-
"Check for API design patterns and service boundaries",
77-
"Examine how different parts of the system communicate",
78-
],
79-
}
80-
case "debug":
81-
return {
82-
path: ".roo/rules-debug/debugging-rules.md",
83-
focus: "Debugging workflow rules, including error investigation approaches, logging strategies, troubleshooting patterns, and debugging best practices",
84-
analysisSteps: [
85-
"Identify logging frameworks and patterns used in the codebase",
86-
"Look for error handling and exception patterns",
87-
"Check for debugging tools or scripts in the project",
88-
"Analyze test structure for debugging approaches",
89-
"Look for monitoring or observability patterns",
90-
],
91-
}
92-
case "docs-extractor":
93-
return {
94-
path: ".roo/rules-docs-extractor/documentation-rules.md",
95-
focus: "Documentation extraction and formatting rules, including documentation style guides, API documentation patterns, and content organization",
96-
analysisSteps: [
97-
"Check for existing documentation files and their formats",
98-
"Analyze code comments and documentation patterns",
99-
"Look for API documentation tools or generators",
100-
"Identify documentation structure and organization patterns",
101-
"Check for examples or tutorials in the codebase",
102-
],
103-
}
104-
default:
105-
return null
106-
}
43+
const definition = ruleTypeDefinitions[type as keyof typeof ruleTypeDefinitions]
44+
return definition || null
10745
})
10846
.filter((rule): rule is RuleInstruction => rule !== null)
10947

110-
// Create a comprehensive message for the rules generation task
111-
const taskMessage = `Analyze this codebase and generate comprehensive rules for AI agents working in this repository.
112-
113-
Your task is to:
114-
115-
1. **Analyze the project structure** by:
116-
${ruleInstructions.map((rule) => ` - For ${rule.path.split("/").pop()}: ${rule.analysisSteps.join("; ")}`).join("\n")}
117-
118-
2. **Look for existing rule files** that might provide guidance:
119-
- Check for CLAUDE.md, .cursorrules, .cursor/rules, or .github/copilot-instructions.md
120-
- If found, incorporate and improve upon their content
121-
122-
3. **Generate and save the following rule files**:
123-
${ruleInstructions
124-
.map(
125-
(rule, index) => `
126-
${index + 1}. **${rule.path}**
127-
- Focus: ${rule.focus}${alwaysAllowWriteProtected ? "\n - The directory has already been created for you" : "\n - Create the necessary directories if they don't exist"}
128-
- Always overwrite the existing file if it exists
129-
- 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"}`,
130-
)
131-
.join("\n")}
132-
133-
4. **Make the rules actionable and specific** by including:
134-
- Build/lint/test commands (especially for running single tests)
135-
- Code style guidelines including imports, formatting, types, naming conventions
136-
- Error handling patterns specific to this project
137-
- Project-specific conventions and best practices
138-
- File organization patterns
139-
140-
5. **Keep rules concise** - aim for 20 lines per file, focusing on the most important guidelines
141-
142-
6. **Open the generated files** in the editor for review after creation
143-
144-
Use the \`safeWriteJson\` utility from \`src/utils/safeWriteJson.ts\` for any JSON file operations to ensure atomic writes.
145-
146-
${
147-
addToGitignore
148-
? `7. **Add the generated files to .gitignore**:
149-
- After generating all rule files, add entries to .gitignore to prevent them from being committed
150-
- Add each generated file path to .gitignore (e.g., .roo/rules/coding-standards.md)
151-
- If .gitignore doesn't exist, create it
152-
- If the entries already exist in .gitignore, don't duplicate them`
153-
: ""
154-
}
155-
156-
${
157-
includeCustomRules && customRulesText
158-
? `\n**Additional rules from User to add to the rules file:**\n${customRulesText}`
159-
: ""
160-
}`
48+
const options: RulesGenerationOptions = {
49+
selectedRuleTypes,
50+
addToGitignore,
51+
alwaysAllowWriteProtected,
52+
includeCustomRules,
53+
customRulesText,
54+
}
16155

162-
return taskMessage
56+
return generateRulesInstructions(ruleInstructions, options)
16357
}

0 commit comments

Comments
 (0)