Review feedback

This commit is contained in:
Matt Rubens
2025-01-23 15:56:24 -08:00
parent f86e96d157
commit 3257dffa56
4 changed files with 179 additions and 140 deletions

View File

@@ -104,17 +104,17 @@
}, },
{ {
"command": "roo-cline.explainCode", "command": "roo-cline.explainCode",
"title": "Explain Code", "title": "Roo Code: Explain Code",
"category": "Roo Code" "category": "Roo Code"
}, },
{ {
"command": "roo-cline.fixCode", "command": "roo-cline.fixCode",
"title": "Fix Code", "title": "Roo Code: Fix Code",
"category": "Roo Code" "category": "Roo Code"
}, },
{ {
"command": "roo-cline.improveCode", "command": "roo-cline.improveCode",
"title": "Improve Code", "title": "Roo Code: Improve Code",
"category": "Roo Code" "category": "Roo Code"
} }
], ],

View File

@@ -171,17 +171,21 @@ export function activate(context: vscode.ExtensionContext) {
context: vscode.ExtensionContext, context: vscode.ExtensionContext,
command: string, command: string,
promptType: keyof typeof ACTION_NAMES, promptType: keyof typeof ACTION_NAMES,
inputPrompt: string, inputPrompt?: string,
inputPlaceholder: string, inputPlaceholder?: string,
) => { ) => {
let userInput: string | undefined
context.subscriptions.push( context.subscriptions.push(
vscode.commands.registerCommand( vscode.commands.registerCommand(
command, command,
async (filePath: string, selectedText: string, diagnostics?: any[]) => { async (filePath: string, selectedText: string, diagnostics?: any[]) => {
const userInput = await vscode.window.showInputBox({ if (inputPrompt) {
prompt: inputPrompt, userInput = await vscode.window.showInputBox({
placeHolder: inputPlaceholder, prompt: inputPrompt,
}) placeHolder: inputPlaceholder,
})
}
const params = { const params = {
filePath, filePath,
@@ -197,29 +201,11 @@ export function activate(context: vscode.ExtensionContext) {
} }
// Register code action commands // Register code action commands
registerCodeAction( registerCodeAction(context, "roo-cline.explainCode", "EXPLAIN")
context,
"roo-cline.explainCode",
"EXPLAIN",
"What would you like Roo to explain?",
"E.g. How does the error handling work?",
)
registerCodeAction( registerCodeAction(context, "roo-cline.fixCode", "FIX")
context,
"roo-cline.fixCode",
"FIX",
"What would you like Roo to fix?",
"E.g. Maintain backward compatibility",
)
registerCodeAction( registerCodeAction(context, "roo-cline.improveCode", "IMPROVE")
context,
"roo-cline.improveCode",
"IMPROVE",
"What would you like Roo to improve?",
"E.g. Focus on performance optimization",
)
return createClineAPI(outputChannel, sidebarProvider) return createClineAPI(outputChannel, sidebarProvider)
} }

View File

@@ -24,7 +24,26 @@ export const createPrompt = (template: string, params: PromptParams): string =>
return result return result
} }
const EXPLAIN_TEMPLATE = `Explain the following code from file path @/\${filePath}: interface SupportPromptConfig {
label: string
description: string
template: string
}
const supportPromptConfigs: Record<string, SupportPromptConfig> = {
ENHANCE: {
label: "Enhance Prompt",
description:
"Use prompt enhancement to get tailored suggestions or improvements for your inputs. This ensures Roo understands your intent and provides the best possible responses. Available via the ✨ icon in chat.",
template: `Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):
\${userInput}`,
},
EXPLAIN: {
label: "Explain Code",
description:
"Get detailed explanations of code snippets, functions, or entire files. Useful for understanding complex code or learning new patterns. Available in the editor context menu (right-click on selected code).",
template: `Explain the following code from file path @/\${filePath}:
\${userInput} \${userInput}
\`\`\` \`\`\`
@@ -34,10 +53,13 @@ const EXPLAIN_TEMPLATE = `Explain the following code from file path @/\${filePat
Please provide a clear and concise explanation of what this code does, including: Please provide a clear and concise explanation of what this code does, including:
1. The purpose and functionality 1. The purpose and functionality
2. Key components and their interactions 2. Key components and their interactions
3. Important patterns or techniques used 3. Important patterns or techniques used`,
` },
FIX: {
const FIX_TEMPLATE = `Fix any issues in the following code from file path @/\${filePath} label: "Fix Issues",
description:
"Get help identifying and resolving bugs, errors, or code quality issues. Provides step-by-step guidance for fixing problems. Available in the editor context menu (right-click on selected code).",
template: `Fix any issues in the following code from file path @/\${filePath}
\${diagnosticText} \${diagnosticText}
\${userInput} \${userInput}
@@ -49,10 +71,13 @@ Please:
1. Address all detected problems listed above (if any) 1. Address all detected problems listed above (if any)
2. Identify any other potential bugs or issues 2. Identify any other potential bugs or issues
3. Provide corrected code 3. Provide corrected code
4. Explain what was fixed and why 4. Explain what was fixed and why`,
` },
IMPROVE: {
const IMPROVE_TEMPLATE = `Improve the following code from file path @/\${filePath}: label: "Improve Code",
description:
"Receive suggestions for code optimization, better practices, and architectural improvements while maintaining functionality. Available in the editor context menu (right-click on selected code).",
template: `Improve the following code from file path @/\${filePath}:
\${userInput} \${userInput}
\`\`\` \`\`\`
@@ -65,27 +90,16 @@ Please suggest improvements for:
3. Best practices and patterns 3. Best practices and patterns
4. Error handling and edge cases 4. Error handling and edge cases
Provide the improved code along with explanations for each enhancement. Provide the improved code along with explanations for each enhancement.`,
` },
const ENHANCE_TEMPLATE = `Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):
\${userInput}`
// Get template based on prompt type
const defaultTemplates = {
EXPLAIN: EXPLAIN_TEMPLATE,
FIX: FIX_TEMPLATE,
IMPROVE: IMPROVE_TEMPLATE,
ENHANCE: ENHANCE_TEMPLATE,
} as const } as const
type SupportPromptType = keyof typeof defaultTemplates type SupportPromptType = keyof typeof supportPromptConfigs
export const supportPrompt = { export const supportPrompt = {
default: defaultTemplates, default: Object.fromEntries(Object.entries(supportPromptConfigs).map(([key, config]) => [key, config.template])),
get: (customSupportPrompts: Record<string, any> | undefined, type: SupportPromptType): string => { get: (customSupportPrompts: Record<string, any> | undefined, type: SupportPromptType): string => {
return customSupportPrompts?.[type] ?? defaultTemplates[type] return customSupportPrompts?.[type] ?? supportPromptConfigs[type].template
}, },
create: (type: SupportPromptType, params: PromptParams, customSupportPrompts?: Record<string, any>): string => { create: (type: SupportPromptType, params: PromptParams, customSupportPrompts?: Record<string, any>): string => {
const template = supportPrompt.get(customSupportPrompts, type) const template = supportPrompt.get(customSupportPrompts, type)
@@ -95,13 +109,14 @@ export const supportPrompt = {
export type { SupportPromptType } export type { SupportPromptType }
// User-friendly labels for support prompt types // Expose labels and descriptions for UI
export const supportPromptLabels: Record<SupportPromptType, string> = { export const supportPromptLabels = Object.fromEntries(
FIX: "Fix Issues", Object.entries(supportPromptConfigs).map(([key, config]) => [key, config.label]),
EXPLAIN: "Explain Code", ) as Record<SupportPromptType, string>
IMPROVE: "Improve Code",
ENHANCE: "Enhance Prompt", export const supportPromptDescriptions = Object.fromEntries(
} as const Object.entries(supportPromptConfigs).map(([key, config]) => [key, config.description]),
) as Record<SupportPromptType, string>
export type CustomSupportPrompts = { export type CustomSupportPrompts = {
[key: string]: string | undefined [key: string]: string | undefined

View File

@@ -9,7 +9,12 @@ import {
} from "@vscode/webview-ui-toolkit/react" } from "@vscode/webview-ui-toolkit/react"
import { useExtensionState } from "../../context/ExtensionStateContext" import { useExtensionState } from "../../context/ExtensionStateContext"
import { Mode, PromptComponent, getRoleDefinition, getAllModes, ModeConfig } from "../../../../src/shared/modes" import { Mode, PromptComponent, getRoleDefinition, getAllModes, ModeConfig } from "../../../../src/shared/modes"
import { supportPrompt, SupportPromptType, supportPromptLabels } from "../../../../src/shared/support-prompt" import {
supportPrompt,
SupportPromptType,
supportPromptLabels,
supportPromptDescriptions,
} from "../../../../src/shared/support-prompt"
import { TOOL_GROUPS, GROUP_DISPLAY_NAMES, ToolGroup } from "../../../../src/shared/tool-groups" import { TOOL_GROUPS, GROUP_DISPLAY_NAMES, ToolGroup } from "../../../../src/shared/tool-groups"
import { vscode } from "../../utils/vscode" import { vscode } from "../../utils/vscode"
@@ -46,7 +51,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
const [selectedPromptTitle, setSelectedPromptTitle] = useState("") const [selectedPromptTitle, setSelectedPromptTitle] = useState("")
const [isToolsEditMode, setIsToolsEditMode] = useState(false) const [isToolsEditMode, setIsToolsEditMode] = useState(false)
const [isCreateModeDialogOpen, setIsCreateModeDialogOpen] = useState(false) const [isCreateModeDialogOpen, setIsCreateModeDialogOpen] = useState(false)
const [activeSupportTab, setActiveSupportTab] = useState<SupportPromptType>("EXPLAIN") const [activeSupportTab, setActiveSupportTab] = useState<SupportPromptType>("ENHANCE")
// Direct update functions // Direct update functions
const updateAgentPrompt = useCallback( const updateAgentPrompt = useCallback(
@@ -313,7 +318,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
</div> </div>
<div style={{ flex: 1, overflow: "auto", padding: "0 20px" }}> <div style={{ flex: 1, overflow: "auto", padding: "0 20px" }}>
<div style={{ marginBottom: "20px" }}> <div style={{ paddingBottom: "20px", borderBottom: "1px solid var(--vscode-input-border)" }}>
<div style={{ marginBottom: "20px" }}> <div style={{ marginBottom: "20px" }}>
<div style={{ fontWeight: "bold", marginBottom: "4px" }}>Preferred Language</div> <div style={{ fontWeight: "bold", marginBottom: "4px" }}>Preferred Language</div>
<select <select
@@ -386,7 +391,13 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
style={{ width: "100%" }} style={{ width: "100%" }}
data-testid="global-custom-instructions-textarea" data-testid="global-custom-instructions-textarea"
/> />
<div style={{ fontSize: "12px", color: "var(--vscode-descriptionForeground)", marginTop: "5px" }}> <div
style={{
fontSize: "12px",
color: "var(--vscode-descriptionForeground)",
marginTop: "5px",
marginBottom: "40px",
}}>
Instructions can also be loaded from{" "} Instructions can also be loaded from{" "}
<span <span
style={{ style={{
@@ -410,7 +421,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
</div> </div>
</div> </div>
<div style={{ marginBottom: "20px" }}> <div style={{ marginTop: "20px" }}>
<div <div
style={{ style={{
display: "flex", display: "flex",
@@ -736,7 +747,14 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
</div> </div>
</div> </div>
</div> </div>
<div style={{ marginBottom: "20px", display: "flex", justifyContent: "flex-start" }}> <div
style={{
paddingBottom: "40px",
marginBottom: "20px",
borderBottom: "1px solid var(--vscode-input-border)",
display: "flex",
justifyContent: "flex-start",
}}>
<VSCodeButton <VSCodeButton
appearance="primary" appearance="primary"
onClick={() => { onClick={() => {
@@ -753,8 +771,13 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
</VSCodeButton> </VSCodeButton>
</div> </div>
<div style={{ marginBottom: "20px" }}> <div
<div style={{ fontWeight: "bold", marginBottom: "12px" }}>Support Prompts</div> style={{
marginTop: "20px",
paddingBottom: "60px",
borderBottom: "1px solid var(--vscode-input-border)",
}}>
<h3 style={{ color: "var(--vscode-foreground)", marginBottom: "12px" }}>Support Prompts</h3>
<div <div
style={{ style={{
display: "flex", display: "flex",
@@ -790,6 +813,16 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
))} ))}
</div> </div>
{/* Support prompt description */}
<div
style={{
fontSize: "13px",
color: "var(--vscode-descriptionForeground)",
margin: "8px 0 16px",
}}>
{supportPromptDescriptions[activeSupportTab]}
</div>
{/* Show active tab content */} {/* Show active tab content */}
<div key={activeSupportTab}> <div key={activeSupportTab}>
<div <div
@@ -799,7 +832,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
alignItems: "center", alignItems: "center",
marginBottom: "4px", marginBottom: "4px",
}}> }}>
<div style={{ fontWeight: "bold" }}>{activeSupportTab} Prompt</div> <div style={{ fontWeight: "bold" }}>Prompt</div>
<VSCodeButton <VSCodeButton
appearance="icon" appearance="icon"
onClick={() => handleSupportReset(activeSupportTab)} onClick={() => handleSupportReset(activeSupportTab)}
@@ -808,49 +841,6 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
</VSCodeButton> </VSCodeButton>
</div> </div>
{activeSupportTab === "ENHANCE" && (
<div>
<div
style={{
color: "var(--vscode-foreground)",
fontSize: "13px",
marginBottom: "20px",
marginTop: "5px",
}}>
Use prompt enhancement to get tailored suggestions or improvements for your inputs.
This ensures Roo understands your intent and provides the best possible responses.
</div>
<div style={{ marginBottom: "12px" }}>
<div style={{ marginBottom: "8px" }}>
<div style={{ fontWeight: "bold", marginBottom: "4px" }}>API Configuration</div>
<div style={{ fontSize: "13px", color: "var(--vscode-descriptionForeground)" }}>
You can select an API configuration to always use for enhancing prompts, or
just use whatever is currently selected
</div>
</div>
<VSCodeDropdown
value={enhancementApiConfigId || ""}
data-testid="api-config-dropdown"
onChange={(e: any) => {
const value = e.detail?.target?.value || e.target?.value
setEnhancementApiConfigId(value)
vscode.postMessage({
type: "enhancementApiConfigId",
text: value,
})
}}
style={{ width: "300px" }}>
<VSCodeOption value="">Use currently selected API configuration</VSCodeOption>
{(listApiConfigMeta || []).map((config) => (
<VSCodeOption key={config.id} value={config.id}>
{config.name}
</VSCodeOption>
))}
</VSCodeDropdown>
</div>
</div>
)}
<VSCodeTextArea <VSCodeTextArea
value={getSupportPromptValue(activeSupportTab)} value={getSupportPromptValue(activeSupportTab)}
onChange={(e) => { onChange={(e) => {
@@ -860,38 +850,86 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
const trimmedValue = value.trim() const trimmedValue = value.trim()
updateSupportPrompt(activeSupportTab, trimmedValue || undefined) updateSupportPrompt(activeSupportTab, trimmedValue || undefined)
}} }}
rows={4} rows={6}
resize="vertical" resize="vertical"
style={{ width: "100%" }} style={{ width: "100%" }}
/> />
{activeSupportTab === "ENHANCE" && ( {activeSupportTab === "ENHANCE" && (
<div style={{ marginTop: "12px" }}> <>
<VSCodeTextArea <div>
value={testPrompt} <div
onChange={(e) => setTestPrompt((e.target as HTMLTextAreaElement).value)} style={{
placeholder="Enter a prompt to test the enhancement" color: "var(--vscode-foreground)",
rows={3} fontSize: "13px",
resize="vertical" marginBottom: "20px",
style={{ width: "100%" }} marginTop: "5px",
data-testid="test-prompt-textarea" }}></div>
/> <div style={{ marginBottom: "12px" }}>
<div <div style={{ marginBottom: "8px" }}>
style={{ <div style={{ fontWeight: "bold", marginBottom: "4px" }}>
marginTop: "8px", API Configuration
display: "flex", </div>
justifyContent: "flex-start", <div
alignItems: "center", style={{
gap: 8, fontSize: "13px",
}}> color: "var(--vscode-descriptionForeground)",
<VSCodeButton }}>
onClick={handleTestEnhancement} You can select an API configuration to always use for enhancing prompts,
disabled={isEnhancing} or just use whatever is currently selected
appearance="primary"> </div>
Preview Prompt Enhancement </div>
</VSCodeButton> <VSCodeDropdown
value={enhancementApiConfigId || ""}
data-testid="api-config-dropdown"
onChange={(e: any) => {
const value = e.detail?.target?.value || e.target?.value
setEnhancementApiConfigId(value)
vscode.postMessage({
type: "enhancementApiConfigId",
text: value,
})
}}
style={{ width: "300px" }}>
<VSCodeOption value="">
Use currently selected API configuration
</VSCodeOption>
{(listApiConfigMeta || []).map((config) => (
<VSCodeOption key={config.id} value={config.id}>
{config.name}
</VSCodeOption>
))}
</VSCodeDropdown>
</div>
</div> </div>
</div>
<div style={{ marginTop: "12px" }}>
<VSCodeTextArea
value={testPrompt}
onChange={(e) => setTestPrompt((e.target as HTMLTextAreaElement).value)}
placeholder="Enter a prompt to test the enhancement"
rows={3}
resize="vertical"
style={{ width: "100%" }}
data-testid="test-prompt-textarea"
/>
<div
style={{
marginTop: "8px",
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
gap: 8,
}}>
<VSCodeButton
onClick={handleTestEnhancement}
disabled={isEnhancing}
appearance="primary">
Preview Prompt Enhancement
</VSCodeButton>
</div>
</div>
</>
)} )}
</div> </div>
</div> </div>