mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
basically working
This commit is contained in:
parent
586e2379e2
commit
83903797cc
6 changed files with 433 additions and 32 deletions
|
|
@ -1899,12 +1899,38 @@ export const webviewMessageHandler = async (
|
|||
// Import the rules generation service
|
||||
const { createRulesGenerationTaskMessage } = await import("../../services/rules/rulesGenerator")
|
||||
|
||||
// Get selected rule types and options from the message
|
||||
const selectedRuleTypes = message.selectedRuleTypes || ["general"]
|
||||
const addToGitignore = message.addToGitignore || false
|
||||
const alwaysAllowWriteProtected = message.alwaysAllowWriteProtected || false
|
||||
const apiConfigName = message.apiConfigName
|
||||
|
||||
// Save current API config to restore later
|
||||
const currentApiConfig = getGlobalState("currentApiConfigName")
|
||||
|
||||
// Temporarily switch to the selected API config if provided
|
||||
if (apiConfigName && apiConfigName !== currentApiConfig) {
|
||||
await updateGlobalState("currentApiConfigName", apiConfigName)
|
||||
await provider.postStateToWebview()
|
||||
}
|
||||
|
||||
// Create a comprehensive message for the rules generation task using existing analysis logic
|
||||
const rulesGenerationMessage = await createRulesGenerationTaskMessage(workspacePath)
|
||||
const rulesGenerationMessage = await createRulesGenerationTaskMessage(
|
||||
workspacePath,
|
||||
selectedRuleTypes,
|
||||
addToGitignore,
|
||||
alwaysAllowWriteProtected,
|
||||
)
|
||||
|
||||
// Spawn a new task in code mode to generate the rules
|
||||
await provider.initClineWithTask(rulesGenerationMessage)
|
||||
|
||||
// Restore the original API config
|
||||
if (apiConfigName && apiConfigName !== currentApiConfig) {
|
||||
await updateGlobalState("currentApiConfigName", currentApiConfig)
|
||||
await provider.postStateToWebview()
|
||||
}
|
||||
|
||||
// Send success message back to webview indicating task was created
|
||||
await provider.postMessageToWebview({
|
||||
type: "rulesGenerationStatus",
|
||||
|
|
@ -1927,6 +1953,45 @@ export const webviewMessageHandler = async (
|
|||
})
|
||||
}
|
||||
break
|
||||
case "checkExistingRuleFiles":
|
||||
// Check which rule files already exist
|
||||
try {
|
||||
const workspacePath = getWorkspacePath()
|
||||
if (!workspacePath) {
|
||||
break
|
||||
}
|
||||
|
||||
const { fileExistsAtPath } = await import("../../utils/fs")
|
||||
const path = await import("path")
|
||||
|
||||
const ruleTypeToPath: Record<string, string> = {
|
||||
general: path.join(workspacePath, ".roo", "rules", "coding-standards.md"),
|
||||
code: path.join(workspacePath, ".roo", "rules-code", "implementation-rules.md"),
|
||||
architect: path.join(workspacePath, ".roo", "rules-architect", "architecture-rules.md"),
|
||||
debug: path.join(workspacePath, ".roo", "rules-debug", "debugging-rules.md"),
|
||||
"docs-extractor": path.join(
|
||||
workspacePath,
|
||||
".roo",
|
||||
"rules-docs-extractor",
|
||||
"documentation-rules.md",
|
||||
),
|
||||
}
|
||||
|
||||
const existingFiles: string[] = []
|
||||
for (const [type, filePath] of Object.entries(ruleTypeToPath)) {
|
||||
if (await fileExistsAtPath(filePath)) {
|
||||
existingFiles.push(type)
|
||||
}
|
||||
}
|
||||
|
||||
await provider.postMessageToWebview({
|
||||
type: "existingRuleFiles",
|
||||
files: existingFiles,
|
||||
})
|
||||
} catch (error) {
|
||||
// Silently fail - not critical
|
||||
}
|
||||
break
|
||||
case "humanRelayResponse":
|
||||
if (message.requestId && message.text) {
|
||||
vscode.commands.executeCommand(getCommand("handleHumanRelayResponse"), {
|
||||
|
|
|
|||
|
|
@ -204,19 +204,73 @@ async function generateCodebaseSummary(workspacePath: string, config: ProjectCon
|
|||
/**
|
||||
* Creates a comprehensive task message for rules generation that can be used with initClineWithTask
|
||||
*/
|
||||
export async function createRulesGenerationTaskMessage(workspacePath: string): Promise<string> {
|
||||
export async function createRulesGenerationTaskMessage(
|
||||
workspacePath: string,
|
||||
selectedRuleTypes: string[],
|
||||
addToGitignore: boolean,
|
||||
alwaysAllowWriteProtected: boolean = false,
|
||||
): Promise<string> {
|
||||
// Analyze the project to get context
|
||||
const config = await analyzeProjectConfig(workspacePath)
|
||||
const codebaseSummary = await generateCodebaseSummary(workspacePath, config)
|
||||
|
||||
// Ensure .roo/rules directory exists at project root
|
||||
const rooRulesDir = path.join(workspacePath, ".roo", "rules")
|
||||
try {
|
||||
await fs.mkdir(rooRulesDir, { recursive: true })
|
||||
} catch (error) {
|
||||
// Directory might already exist, which is fine
|
||||
// Ensure all necessary directories exist at project root
|
||||
const directoriesToCreate = [
|
||||
path.join(workspacePath, ".roo", "rules"),
|
||||
path.join(workspacePath, ".roo", "rules-code"),
|
||||
path.join(workspacePath, ".roo", "rules-architect"),
|
||||
path.join(workspacePath, ".roo", "rules-debug"),
|
||||
path.join(workspacePath, ".roo", "rules-docs-extractor"),
|
||||
]
|
||||
|
||||
for (const dir of directoriesToCreate) {
|
||||
try {
|
||||
await fs.mkdir(dir, { recursive: true })
|
||||
} catch (error) {
|
||||
// Directory might already exist, which is fine
|
||||
}
|
||||
}
|
||||
|
||||
// Create rule-specific instructions based on selected types
|
||||
interface RuleInstruction {
|
||||
path: string
|
||||
focus: 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",
|
||||
}
|
||||
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",
|
||||
}
|
||||
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",
|
||||
}
|
||||
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",
|
||||
}
|
||||
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",
|
||||
}
|
||||
default:
|
||||
return 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.
|
||||
|
||||
|
|
@ -233,10 +287,17 @@ ${codebaseSummary}
|
|||
- Project-specific conventions and best practices
|
||||
- File organization patterns
|
||||
|
||||
3. **Save the rules** to the file at exactly this path: .roo/rules/coding-standards.md
|
||||
- The .roo/rules directory has already been created for you
|
||||
- Always overwrite the existing file if it exists
|
||||
- Use the \`write_to_file\` tool to save the content
|
||||
3. **Generate and save the following rule files**:
|
||||
${ruleInstructions
|
||||
.map(
|
||||
(rule, index) => `
|
||||
${index + 1}. **${rule.path}**
|
||||
- Focus: ${rule.focus}
|
||||
- The directory has already been created for you
|
||||
- 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" : ""}`,
|
||||
)
|
||||
.join("\n")}
|
||||
|
||||
4. **Open the generated file** in the editor for review
|
||||
|
||||
|
|
@ -244,7 +305,17 @@ The rules should be about 20-30 lines long and focus on the most important guide
|
|||
|
||||
If there are existing rules files (like CLAUDE.md, .cursorrules, .cursor/rules, .github/copilot-instructions.md), incorporate and improve upon them.
|
||||
|
||||
Use the \`safeWriteJson\` utility from \`src/utils/safeWriteJson.ts\` for any JSON file operations to ensure atomic writes.`
|
||||
Use the \`safeWriteJson\` utility from \`src/utils/safeWriteJson.ts\` for any JSON file operations to ensure atomic writes.
|
||||
|
||||
${
|
||||
addToGitignore
|
||||
? `5. **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`
|
||||
: ""
|
||||
}`
|
||||
|
||||
return taskMessage
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,8 +106,10 @@ export interface ExtensionMessage {
|
|||
| "codeIndexSettingsSaved"
|
||||
| "codeIndexSecretStatus"
|
||||
| "rulesGenerationStatus"
|
||||
| "existingRuleFiles"
|
||||
text?: string
|
||||
payload?: any // Add a generic payload for now, can refine later
|
||||
files?: string[] // For existingRuleFiles
|
||||
action?:
|
||||
| "chatButtonClicked"
|
||||
| "mcpButtonClicked"
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ export interface WebviewMessage {
|
|||
| "saveCodeIndexSettingsAtomic"
|
||||
| "requestCodeIndexSecretStatus"
|
||||
| "generateRules"
|
||||
| "checkExistingRuleFiles"
|
||||
text?: string
|
||||
editedMessageContent?: string
|
||||
tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account"
|
||||
|
|
@ -236,6 +237,11 @@ export interface WebviewMessage {
|
|||
visibility?: ShareVisibility // For share visibility
|
||||
hasContent?: boolean // For checkRulesDirectoryResult
|
||||
checkOnly?: boolean // For deleteCustomMode check
|
||||
selectedRuleTypes?: string[] // For generateRules
|
||||
addToGitignore?: boolean // For generateRules
|
||||
alwaysAllowWriteProtected?: boolean // For generateRules
|
||||
apiConfigName?: string // For generateRules
|
||||
files?: string[] // For existingRuleFiles response
|
||||
codeIndexSettings?: {
|
||||
// Global state settings
|
||||
codebaseIndexEnabled: boolean
|
||||
|
|
|
|||
|
|
@ -1,15 +1,25 @@
|
|||
import { HTMLAttributes, useState, useEffect } from "react"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
import { FileText, Loader2 } from "lucide-react"
|
||||
import { FileText, Loader2, AlertTriangle, Info } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { vscode } from "@/utils/vscode"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useExtensionState } from "@/context/ExtensionStateContext"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui"
|
||||
|
||||
import { SectionHeader } from "./SectionHeader"
|
||||
import { Section } from "./Section"
|
||||
|
||||
type RulesSettingsProps = HTMLAttributes<HTMLDivElement>
|
||||
|
||||
interface RuleType {
|
||||
id: string
|
||||
label: string
|
||||
description: string
|
||||
checked: boolean
|
||||
exists?: boolean
|
||||
}
|
||||
|
||||
export const RulesSettings = ({ className, ...props }: RulesSettingsProps) => {
|
||||
const { t } = useAppTranslation()
|
||||
const [isGenerating, setIsGenerating] = useState(false)
|
||||
|
|
@ -17,6 +27,69 @@ export const RulesSettings = ({ className, ...props }: RulesSettingsProps) => {
|
|||
type: "success" | "error" | null
|
||||
message: string
|
||||
}>({ type: null, message: "" })
|
||||
const [addToGitignore, setAddToGitignore] = useState(false)
|
||||
const [_existingFiles, setExistingFiles] = useState<string[]>([])
|
||||
const [alwaysAllowWriteProtected, setAlwaysAllowWriteProtected] = useState(false)
|
||||
const [selectedApiConfig, setSelectedApiConfig] = useState<string>("")
|
||||
|
||||
const { listApiConfigMeta, currentApiConfigName } = useExtensionState()
|
||||
|
||||
const [ruleTypes, setRuleTypes] = useState<RuleType[]>([
|
||||
{
|
||||
id: "general",
|
||||
label: t("settings:rules.types.general.label"),
|
||||
description: t("settings:rules.types.general.description"),
|
||||
checked: true,
|
||||
exists: false,
|
||||
},
|
||||
{
|
||||
id: "code",
|
||||
label: t("settings:rules.types.code.label"),
|
||||
description: t("settings:rules.types.code.description"),
|
||||
checked: true,
|
||||
exists: false,
|
||||
},
|
||||
{
|
||||
id: "architect",
|
||||
label: t("settings:rules.types.architect.label"),
|
||||
description: t("settings:rules.types.architect.description"),
|
||||
checked: true,
|
||||
exists: false,
|
||||
},
|
||||
{
|
||||
id: "debug",
|
||||
label: t("settings:rules.types.debug.label"),
|
||||
description: t("settings:rules.types.debug.description"),
|
||||
checked: true,
|
||||
exists: false,
|
||||
},
|
||||
{
|
||||
id: "docs-extractor",
|
||||
label: t("settings:rules.types.docsExtractor.label"),
|
||||
description: t("settings:rules.types.docsExtractor.description"),
|
||||
checked: true,
|
||||
exists: false,
|
||||
},
|
||||
])
|
||||
|
||||
const handleRuleTypeToggle = (id: string) => {
|
||||
setRuleTypes((prev) => prev.map((rule) => (rule.id === id ? { ...rule, checked: !rule.checked } : rule)))
|
||||
}
|
||||
|
||||
// Check for existing files and get current settings when component mounts
|
||||
useEffect(() => {
|
||||
vscode.postMessage({
|
||||
type: "checkExistingRuleFiles",
|
||||
})
|
||||
|
||||
// Request current state to get alwaysAllowWriteProtected value
|
||||
vscode.postMessage({ type: "webviewDidLaunch" })
|
||||
|
||||
// Set default API config
|
||||
if (currentApiConfigName && !selectedApiConfig) {
|
||||
setSelectedApiConfig(currentApiConfigName)
|
||||
}
|
||||
}, [currentApiConfigName, selectedApiConfig])
|
||||
|
||||
useEffect(() => {
|
||||
const handleMessage = (event: MessageEvent) => {
|
||||
|
|
@ -34,6 +107,20 @@ export const RulesSettings = ({ className, ...props }: RulesSettingsProps) => {
|
|||
message: message.error || "Unknown error occurred",
|
||||
})
|
||||
}
|
||||
} else if (message.type === "existingRuleFiles") {
|
||||
setExistingFiles(message.files || [])
|
||||
// Update rule types with existence information
|
||||
setRuleTypes((prev) =>
|
||||
prev.map((rule) => ({
|
||||
...rule,
|
||||
exists: message.files?.includes(rule.id) || false,
|
||||
})),
|
||||
)
|
||||
} else if (message.type === "state") {
|
||||
// Update alwaysAllowWriteProtected from the extension state
|
||||
if (message.state?.alwaysAllowWriteProtected !== undefined) {
|
||||
setAlwaysAllowWriteProtected(message.state.alwaysAllowWriteProtected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,15 +129,31 @@ export const RulesSettings = ({ className, ...props }: RulesSettingsProps) => {
|
|||
}, [])
|
||||
|
||||
const handleGenerateRules = () => {
|
||||
const selectedRules = ruleTypes.filter((rule) => rule.checked)
|
||||
if (selectedRules.length === 0) {
|
||||
setGenerationStatus({
|
||||
type: "error",
|
||||
message: t("settings:rules.noRulesSelected"),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
setIsGenerating(true)
|
||||
setGenerationStatus({ type: null, message: "" })
|
||||
|
||||
// Send message to extension to generate rules
|
||||
vscode.postMessage({
|
||||
type: "generateRules",
|
||||
selectedRuleTypes: selectedRules.map((rule) => rule.id),
|
||||
addToGitignore,
|
||||
alwaysAllowWriteProtected,
|
||||
apiConfigName: selectedApiConfig,
|
||||
})
|
||||
}
|
||||
|
||||
const existingRules = ruleTypes.filter((rule) => rule.checked && rule.exists)
|
||||
const hasExistingFiles = existingRules.length > 0
|
||||
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-2", className)} {...props}>
|
||||
<SectionHeader>
|
||||
|
|
@ -64,23 +167,144 @@ export const RulesSettings = ({ className, ...props }: RulesSettingsProps) => {
|
|||
<div className="space-y-4">
|
||||
<p className="text-vscode-descriptionForeground text-sm">{t("settings:rules.description")}</p>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<Button
|
||||
onClick={handleGenerateRules}
|
||||
disabled={isGenerating}
|
||||
variant="default"
|
||||
size="default"
|
||||
className="w-fit"
|
||||
title={t("settings:rules.generateButtonTooltip")}>
|
||||
{isGenerating ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
{t("settings:rules.generating")}
|
||||
</>
|
||||
) : (
|
||||
t("settings:rules.generateButton")
|
||||
)}
|
||||
</Button>
|
||||
{/* Recommendation box */}
|
||||
<div className="flex items-start gap-2 p-3 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")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-medium mb-3">{t("settings:rules.selectTypes")}</h4>
|
||||
<div className="grid grid-cols-[repeat(auto-fill,minmax(200px,1fr))] gap-2">
|
||||
{ruleTypes.map((ruleType) => (
|
||||
<div
|
||||
key={ruleType.id}
|
||||
onClick={() => handleRuleTypeToggle(ruleType.id)}
|
||||
className={cn(
|
||||
"relative p-3 rounded-md border cursor-pointer transition-all",
|
||||
"hover:border-vscode-focusBorder",
|
||||
ruleType.checked
|
||||
? "bg-vscode-list-activeSelectionBackground border-vscode-focusBorder"
|
||||
: "bg-vscode-editor-background border-vscode-panel-border",
|
||||
)}>
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-medium flex items-center gap-1">
|
||||
{ruleType.label}
|
||||
{ruleType.exists && (
|
||||
<span
|
||||
className="text-vscode-testing-iconQueued"
|
||||
title={t("settings:rules.fileExists")}>
|
||||
•
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-xs text-vscode-descriptionForeground mt-1">
|
||||
{ruleType.description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{hasExistingFiles && (
|
||||
<div className="flex items-start gap-2 p-3 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>
|
||||
<ul className="mt-1 ml-4 list-disc">
|
||||
{existingRules.map((rule) => (
|
||||
<li key={rule.id}>{rule.label}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</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"
|
||||
checked={addToGitignore}
|
||||
onChange={(e) => setAddToGitignore(e.target.checked)}
|
||||
/>
|
||||
<div>
|
||||
<div className="text-sm font-medium">{t("settings:rules.addToGitignore")}</div>
|
||||
<div className="text-xs text-vscode-descriptionForeground">
|
||||
{t("settings:rules.addToGitignoreDescription")}
|
||||
</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"
|
||||
checked={alwaysAllowWriteProtected}
|
||||
onChange={(e) => {
|
||||
setAlwaysAllowWriteProtected(e.target.checked)
|
||||
vscode.postMessage({
|
||||
type: "alwaysAllowWriteProtected",
|
||||
bool: e.target.checked,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<div className="text-sm font-medium">
|
||||
{t("settings:rules.autoApproveProtected")}
|
||||
</div>
|
||||
<div className="text-xs text-vscode-descriptionForeground">
|
||||
{t("settings:rules.autoApproveProtectedDescription")}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-48">
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
{t("settings:rules.apiConfigLabel")}
|
||||
</label>
|
||||
<Select value={selectedApiConfig} onValueChange={setSelectedApiConfig}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("settings:rules.selectApiConfig")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{(listApiConfigMeta || []).map((config) => (
|
||||
<SelectItem key={config.id} value={config.name}>
|
||||
{config.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleGenerateRules}
|
||||
disabled={isGenerating || !selectedApiConfig}
|
||||
variant="default"
|
||||
size="default"
|
||||
className="mt-6"
|
||||
title={t("settings:rules.generateButtonTooltip")}>
|
||||
{isGenerating ? (
|
||||
<>
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
{t("settings:rules.generating")}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FileText className="mr-2 h-4 w-4" />
|
||||
{t("settings:rules.generateButton")}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isGenerating && (
|
||||
<p className="text-vscode-descriptionForeground text-sm">
|
||||
|
|
|
|||
|
|
@ -619,7 +619,40 @@
|
|||
"existingRules": "Existing rules detected",
|
||||
"existingRulesDescription": "Rules already exist at {{path}}. Generating new rules will create a timestamped file to preserve your existing rules.",
|
||||
"noWorkspace": "No workspace folder open",
|
||||
"noWorkspaceDescription": "Please open a workspace folder to generate rules for your project."
|
||||
"noWorkspaceDescription": "Please open a workspace folder to generate rules for your project.",
|
||||
"selectTypes": "Select rule types to generate:",
|
||||
"noRulesSelected": "Please select at least one rule type to generate",
|
||||
"types": {
|
||||
"general": {
|
||||
"label": "General Rules",
|
||||
"description": "General coding standards applied to all modes"
|
||||
},
|
||||
"code": {
|
||||
"label": "Code Mode Rules",
|
||||
"description": "Specific rules for code syntax, implementation details, and best practices"
|
||||
},
|
||||
"architect": {
|
||||
"label": "Architect Mode Rules",
|
||||
"description": "Rules for high-level system design, file organization, and architecture patterns"
|
||||
},
|
||||
"debug": {
|
||||
"label": "Debug Mode Rules",
|
||||
"description": "Rules for debugging workflows, error handling, and troubleshooting approaches"
|
||||
},
|
||||
"docsExtractor": {
|
||||
"label": "Documentation Rules",
|
||||
"description": "Rules for documentation extraction and formatting standards"
|
||||
}
|
||||
},
|
||||
"fileExists": "File exists",
|
||||
"overwriteWarning": "Warning: The following rule files already exist and will be overwritten:",
|
||||
"addToGitignore": "Add to .gitignore",
|
||||
"addToGitignoreDescription": "Automatically add the generated rule files to .gitignore to prevent them from being committed to version control",
|
||||
"autoApproveProtected": "Auto-approve protected file writes",
|
||||
"autoApproveProtectedDescription": "Allow Roo to write to .roo directory without requiring manual approval",
|
||||
"autoApproveRecommendation": "For the best experience generating rules, we recommend enabling auto-approve for both read and write operations in the Auto-Approve settings above.",
|
||||
"apiConfigLabel": "API Configuration",
|
||||
"selectApiConfig": "Select API configuration"
|
||||
},
|
||||
"promptCaching": {
|
||||
"label": "Disable prompt caching",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue