refactor: consolidate prompt functionality into support-prompt module

- Move code action prompts from core/prompts to shared/support-prompt
- Migrate enhance prompt functionality from modes to support-prompt
- Add UI for managing code action prompts in PromptsView
- Update types and interfaces for better prompt management
This commit is contained in:
sam hoang
2025-01-23 00:31:43 +07:00
parent 7845791720
commit 22907a0578
9 changed files with 467 additions and 268 deletions

View File

@@ -1,76 +0,0 @@
import { explainCodePrompt, fixCodePrompt, improveCodePrompt } from '../code-actions';
describe('Code Action Prompts', () => {
const testFilePath = 'test/file.ts';
const testCode = 'function test() { return true; }';
describe('explainCodePrompt', () => {
it('should format explain prompt correctly', () => {
const prompt = explainCodePrompt({
filePath: testFilePath,
selectedText: testCode
});
expect(prompt).toContain(`@/${testFilePath}`);
expect(prompt).toContain(testCode);
expect(prompt).toContain('purpose and functionality');
expect(prompt).toContain('Key components');
expect(prompt).toContain('Important patterns');
});
});
describe('fixCodePrompt', () => {
it('should format fix prompt without diagnostics', () => {
const prompt = fixCodePrompt({
filePath: testFilePath,
selectedText: testCode
});
expect(prompt).toContain(`@/${testFilePath}`);
expect(prompt).toContain(testCode);
expect(prompt).toContain('Address all detected problems');
expect(prompt).not.toContain('Current problems detected');
});
it('should format fix prompt with diagnostics', () => {
const diagnostics = [
{
source: 'eslint',
message: 'Missing semicolon',
code: 'semi'
},
{
message: 'Unused variable',
severity: 1
}
];
const prompt = fixCodePrompt({
filePath: testFilePath,
selectedText: testCode,
diagnostics
});
expect(prompt).toContain('Current problems detected:');
expect(prompt).toContain('[eslint] Missing semicolon (semi)');
expect(prompt).toContain('[Error] Unused variable');
expect(prompt).toContain(testCode);
});
});
describe('improveCodePrompt', () => {
it('should format improve prompt correctly', () => {
const prompt = improveCodePrompt({
filePath: testFilePath,
selectedText: testCode
});
expect(prompt).toContain(`@/${testFilePath}`);
expect(prompt).toContain(testCode);
expect(prompt).toContain('Code readability');
expect(prompt).toContain('Performance optimization');
expect(prompt).toContain('Best practices');
expect(prompt).toContain('Error handling');
});
});
});

View File

@@ -1,87 +0,0 @@
type PromptParams = Record<string, string | any[]>;
const generateDiagnosticText = (diagnostics?: any[]) => {
if (!diagnostics?.length) return '';
return `\nCurrent problems detected:\n${diagnostics.map(d =>
`- [${d.source || 'Error'}] ${d.message}${d.code ? ` (${d.code})` : ''}`
).join('\n')}`;
};
export const createPrompt = (template: string, params: PromptParams): string => {
let result = template;
for (const [key, value] of Object.entries(params)) {
if (key === 'diagnostics') {
result = result.replaceAll('${diagnosticText}', generateDiagnosticText(value as any[]));
} else {
result = result.replaceAll(`\${${key}}`, value as string);
}
}
// Replace any remaining user_input placeholders with empty string
result = result.replaceAll('${userInput}', '');
return result;
};
export const EXPLAIN_TEMPLATE = `
Explain the following code from file path @/\${filePath}:
\${userInput}
\`\`\`
\${selectedText}
\`\`\`
Please provide a clear and concise explanation of what this code does, including:
1. The purpose and functionality
2. Key components and their interactions
3. Important patterns or techniques used
`;
export const FIX_TEMPLATE = `
Fix any issues in the following code from file path @/\${filePath}
\${diagnosticText}
\${userInput}
\`\`\`
\${selectedText}
\`\`\`
Please:
1. Address all detected problems listed above (if any)
2. Identify any other potential bugs or issues
3. Provide corrected code
4. Explain what was fixed and why
`;
export const IMPROVE_TEMPLATE = `
Improve the following code from file path @/\${filePath}:
\${userInput}
\`\`\`
\${selectedText}
\`\`\`
Please suggest improvements for:
1. Code readability and maintainability
2. Performance optimization
3. Best practices and patterns
4. Error handling and edge cases
Provide the improved code along with explanations for each enhancement.
`;
export const explainCodePrompt = (params: PromptParams) =>
createPrompt(EXPLAIN_TEMPLATE, params);
export const fixCodePrompt = (params: PromptParams) =>
createPrompt(FIX_TEMPLATE, params);
export const improveCodePrompt = (params: PromptParams) =>
createPrompt(IMPROVE_TEMPLATE, params);
// Get template based on prompt type
export const defaultTemplates = {
'EXPLAIN': EXPLAIN_TEMPLATE,
'FIX': FIX_TEMPLATE,
'IMPROVE': IMPROVE_TEMPLATE
}

View File

@@ -1,4 +1,5 @@
import { Anthropic } from "@anthropic-ai/sdk"
import delay from "delay"
import axios from "axios"
import fs from "fs/promises"
import os from "os"
@@ -23,7 +24,6 @@ import {
modes,
CustomPrompts,
PromptComponent,
enhance,
ModeConfig,
defaultModeSlug,
getModeBySlug,
@@ -40,10 +40,7 @@ import { enhancePrompt } from "../../utils/enhance-prompt"
import { getCommitInfo, searchCommits, getWorkingState } from "../../utils/git"
import { ConfigManager } from "../config/ConfigManager"
import { CustomModesManager } from "../config/CustomModesManager"
import {
defaultTemplates,
createPrompt
} from "../prompts/code-actions"
import { enhance, codeActionPrompt } from "../../shared/support-prompt"
import { ACTION_NAMES } from "../CodeActionProvider"
@@ -189,17 +186,27 @@ export class ClineProvider implements vscode.WebviewViewProvider {
public static async handleCodeAction(
promptType: keyof typeof ACTION_NAMES,
params: Record<string, string | any[]>
params: Record<string, string | any[]>,
): Promise<void> {
const visibleProvider = ClineProvider.getVisibleInstance()
let visibleProvider = ClineProvider.getVisibleInstance()
// If no visible provider, try to show the sidebar view
if (!visibleProvider) {
await vscode.commands.executeCommand("roo-cline.SidebarProvider.focus")
// Wait briefly for the view to become visible
await delay(100)
visibleProvider = ClineProvider.getVisibleInstance()
}
// If still no visible provider, return
if (!visibleProvider) {
return
}
const { utilPrompt } = await visibleProvider.getState()
const { customPrompts } = await visibleProvider.getState()
const prompt = codeActionPrompt.create(promptType, params, customPrompts)
const template = utilPrompt?.[promptType] ?? defaultTemplates[promptType]
const prompt = createPrompt(template, params)
await visibleProvider.initClineWithTask(prompt)
}
@@ -297,7 +304,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experimentalDiffStrategy,
} = await this.getState()
const modePrompt = customPrompts?.[mode]
const modePrompt = customPrompts?.[mode] as PromptComponent
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
this.cline = new Cline(
@@ -325,7 +332,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
experimentalDiffStrategy,
} = await this.getState()
const modePrompt = customPrompts?.[mode]
const modePrompt = customPrompts?.[mode] as PromptComponent
const effectiveInstructions = [globalInstructions, modePrompt?.customInstructions].filter(Boolean).join("\n\n")
this.cline = new Cline(
@@ -804,29 +811,49 @@ export class ClineProvider implements vscode.WebviewViewProvider {
await this.postStateToWebview()
break
case "updateEnhancedPrompt":
const existingPrompts = (await this.getGlobalState("customPrompts")) || {}
case "updateSupportPrompt":
try {
if (Object.keys(message?.values ?? {}).length === 0) {
return
}
const updatedPrompts = {
...existingPrompts,
enhance: message.text,
const existingPrompts = (await this.getGlobalState("customPrompts")) || {}
const updatedPrompts = {
...existingPrompts,
...message.values,
}
await this.updateGlobalState("customPrompts", updatedPrompts)
await this.postStateToWebview()
} catch (error) {
console.error("Error update support prompt:", error)
vscode.window.showErrorMessage("Failed to update support prompt")
}
break
case "resetSupportPrompt":
try {
if (!message?.text) {
return
}
await this.updateGlobalState("customPrompts", updatedPrompts)
const existingPrompts = ((await this.getGlobalState("customPrompts")) || {}) as Record<
string,
any
>
// Get current state and explicitly include customPrompts
const currentState = await this.getState()
const updatedPrompts = {
...existingPrompts,
}
const stateWithPrompts = {
...currentState,
customPrompts: updatedPrompts,
updatedPrompts[message.text] = undefined
await this.updateGlobalState("customPrompts", updatedPrompts)
await this.postStateToWebview()
} catch (error) {
console.error("Error reset support prompt:", error)
vscode.window.showErrorMessage("Failed to reset support prompt")
}
// Post state with prompts
this.view?.webview.postMessage({
type: "state",
state: stateWithPrompts,
})
break
case "updatePrompt":
if (message.promptMode && message.customPrompt !== undefined) {

View File

@@ -6,7 +6,6 @@ import { ClineProvider } from "./core/webview/ClineProvider"
import { createClineAPI } from "./exports"
import "./utils/path" // necessary to have access to String.prototype.toPosix
import { ACTION_NAMES, CodeActionProvider } from "./core/CodeActionProvider"
import { explainCodePrompt, fixCodePrompt, improveCodePrompt } from "./core/prompts/code-actions"
import { DIFF_VIEW_URI_SCHEME } from "./integrations/editor/DiffViewProvider"
/*
@@ -162,14 +161,10 @@ export function activate(context: vscode.ExtensionContext) {
// Register code actions provider
context.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
{ pattern: "**/*" },
new CodeActionProvider(),
{
providedCodeActionKinds: CodeActionProvider.providedCodeActionKinds
}
)
);
vscode.languages.registerCodeActionsProvider({ pattern: "**/*" }, new CodeActionProvider(), {
providedCodeActionKinds: CodeActionProvider.providedCodeActionKinds,
}),
)
// Helper function to handle code actions
const registerCodeAction = (
@@ -177,51 +172,54 @@ export function activate(context: vscode.ExtensionContext) {
command: string,
promptType: keyof typeof ACTION_NAMES,
inputPrompt: string,
inputPlaceholder: string
inputPlaceholder: string,
) => {
context.subscriptions.push(
vscode.commands.registerCommand(command, async (filePath: string, selectedText: string, diagnostics?: any[]) => {
const userInput = await vscode.window.showInputBox({
prompt: inputPrompt,
placeHolder: inputPlaceholder
});
vscode.commands.registerCommand(
command,
async (filePath: string, selectedText: string, diagnostics?: any[]) => {
const userInput = await vscode.window.showInputBox({
prompt: inputPrompt,
placeHolder: inputPlaceholder,
})
const params = {
filePath,
selectedText,
...(diagnostics ? { diagnostics } : {}),
...(userInput ? { userInput } : {})
};
const params = {
filePath,
selectedText,
...(diagnostics ? { diagnostics } : {}),
...(userInput ? { userInput } : {}),
}
await ClineProvider.handleCodeAction(promptType, params);
})
);
};
await ClineProvider.handleCodeAction(promptType, params)
},
),
)
}
// Register code action commands
registerCodeAction(
context,
"roo-cline.explainCode",
'EXPLAIN',
"EXPLAIN",
"Any specific questions about this code?",
"E.g. How does the error handling work?"
);
"E.g. How does the error handling work?",
)
registerCodeAction(
context,
"roo-cline.fixCode",
'FIX',
"FIX",
"Any specific concerns about fixing this code?",
"E.g. Maintain backward compatibility"
);
"E.g. Maintain backward compatibility",
)
registerCodeAction(
context,
"roo-cline.improveCode",
'IMPROVE',
"IMPROVE",
"Any specific aspects you want to improve?",
"E.g. Focus on performance optimization"
);
"E.g. Focus on performance optimization",
)
return createClineAPI(outputChannel, sidebarProvider)
}

View File

@@ -68,7 +68,8 @@ export interface WebviewMessage {
| "requestVsCodeLmModels"
| "mode"
| "updatePrompt"
| "updateEnhancedPrompt"
| "updateSupportPrompt"
| "resetSupportPrompt"
| "getSystemPrompt"
| "systemPrompt"
| "enhancementApiConfigId"

View File

@@ -0,0 +1,138 @@
import { codeActionPrompt, type CodeActionType } from "../support-prompt"
describe("Code Action Prompts", () => {
const testFilePath = "test/file.ts"
const testCode = "function test() { return true; }"
describe("EXPLAIN action", () => {
it("should format explain prompt correctly", () => {
const prompt = codeActionPrompt.create("EXPLAIN", {
filePath: testFilePath,
selectedText: testCode,
})
expect(prompt).toContain(`@/${testFilePath}`)
expect(prompt).toContain(testCode)
expect(prompt).toContain("purpose and functionality")
expect(prompt).toContain("Key components")
expect(prompt).toContain("Important patterns")
})
})
describe("FIX action", () => {
it("should format fix prompt without diagnostics", () => {
const prompt = codeActionPrompt.create("FIX", {
filePath: testFilePath,
selectedText: testCode,
})
expect(prompt).toContain(`@/${testFilePath}`)
expect(prompt).toContain(testCode)
expect(prompt).toContain("Address all detected problems")
expect(prompt).not.toContain("Current problems detected")
})
it("should format fix prompt with diagnostics", () => {
const diagnostics = [
{
source: "eslint",
message: "Missing semicolon",
code: "semi",
},
{
message: "Unused variable",
severity: 1,
},
]
const prompt = codeActionPrompt.create("FIX", {
filePath: testFilePath,
selectedText: testCode,
diagnostics,
})
expect(prompt).toContain("Current problems detected:")
expect(prompt).toContain("[eslint] Missing semicolon (semi)")
expect(prompt).toContain("[Error] Unused variable")
expect(prompt).toContain(testCode)
})
})
describe("IMPROVE action", () => {
it("should format improve prompt correctly", () => {
const prompt = codeActionPrompt.create("IMPROVE", {
filePath: testFilePath,
selectedText: testCode,
})
expect(prompt).toContain(`@/${testFilePath}`)
expect(prompt).toContain(testCode)
expect(prompt).toContain("Code readability")
expect(prompt).toContain("Performance optimization")
expect(prompt).toContain("Best practices")
expect(prompt).toContain("Error handling")
})
})
describe("get template", () => {
it("should return default template when no custom prompts provided", () => {
const template = codeActionPrompt.get(undefined, "EXPLAIN")
expect(template).toBe(codeActionPrompt.default.EXPLAIN)
})
it("should return custom template when provided", () => {
const customTemplate = "Custom template for explaining code"
const customPrompts = {
EXPLAIN: customTemplate,
}
const template = codeActionPrompt.get(customPrompts, "EXPLAIN")
expect(template).toBe(customTemplate)
})
it("should return default template when custom prompts does not include type", () => {
const customPrompts = {
SOMETHING_ELSE: "Other template",
}
const template = codeActionPrompt.get(customPrompts, "EXPLAIN")
expect(template).toBe(codeActionPrompt.default.EXPLAIN)
})
})
describe("create with custom prompts", () => {
it("should use custom template when provided", () => {
const customTemplate = "Custom template for ${filePath}"
const customPrompts = {
EXPLAIN: customTemplate,
}
const prompt = codeActionPrompt.create(
"EXPLAIN",
{
filePath: testFilePath,
selectedText: testCode,
},
customPrompts,
)
expect(prompt).toContain(`Custom template for ${testFilePath}`)
expect(prompt).not.toContain("purpose and functionality")
})
it("should use default template when custom prompts does not include type", () => {
const customPrompts = {
EXPLAIN: "Other template",
}
const prompt = codeActionPrompt.create(
"EXPLAIN",
{
filePath: testFilePath,
selectedText: testCode,
},
customPrompts,
)
expect(prompt).toContain("Other template")
})
})
})

View File

@@ -12,6 +12,16 @@ export type ModeConfig = {
groups: readonly ToolGroup[] // Now uses groups instead of tools array
}
// Mode-specific prompts only
export type PromptComponent = {
roleDefinition?: string
customInstructions?: string
}
export type CustomPrompts = {
[key: string]: PromptComponent | undefined | string
}
// Helper to get all tools for a mode
export function getToolsForMode(groups: readonly ToolGroup[]): string[] {
const tools = new Set<string>()
@@ -130,33 +140,6 @@ export function isToolAllowedForMode(
return mode.groups.some((group) => TOOL_GROUPS[group].includes(tool as string))
}
export type PromptComponent = {
roleDefinition?: string
customInstructions?: string
}
// Mode-specific prompts only
export type CustomPrompts = {
[key: string]: PromptComponent | undefined
}
// Separate enhance prompt type and definition
export type EnhanceConfig = {
prompt: string
}
export const enhance: EnhanceConfig = {
prompt: "Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):",
} as const
// Completely separate enhance prompt handling
export const enhancePrompt = {
default: enhance.prompt,
get: (customPrompts: Record<string, any> | undefined): string => {
return customPrompts?.enhance ?? enhance.prompt
},
} as const
// Create the mode-specific default prompts
export const defaultPrompts: Readonly<CustomPrompts> = Object.freeze(
Object.fromEntries(modes.map((mode) => [mode.slug, { roleDefinition: mode.roleDefinition }])),

View File

@@ -0,0 +1,118 @@
// Separate enhance prompt type and definition
export type EnhanceConfig = {
prompt: string
}
export const enhance: EnhanceConfig = {
prompt: "Generate an enhanced version of this prompt (reply with only the enhanced prompt - no conversation, explanations, lead-in, bullet points, placeholders, or surrounding quotes):",
} as const
// Completely separate enhance prompt handling
export const enhancePrompt = {
default: enhance.prompt,
get: (customPrompts: Record<string, any> | undefined): string => {
return customPrompts?.enhance ?? enhance.prompt
},
} as const
// Code action prompts
type PromptParams = Record<string, string | any[]>
const generateDiagnosticText = (diagnostics?: any[]) => {
if (!diagnostics?.length) return ""
return `\nCurrent problems detected:\n${diagnostics
.map((d) => `- [${d.source || "Error"}] ${d.message}${d.code ? ` (${d.code})` : ""}`)
.join("\n")}`
}
export const createPrompt = (template: string, params: PromptParams): string => {
let result = template
for (const [key, value] of Object.entries(params)) {
if (key === "diagnostics") {
result = result.replaceAll("${diagnosticText}", generateDiagnosticText(value as any[]))
} else {
result = result.replaceAll(`\${${key}}`, value as string)
}
}
// Replace any remaining user_input placeholders with empty string
result = result.replaceAll("${userInput}", "")
return result
}
const EXPLAIN_TEMPLATE = `
Explain the following code from file path @/\${filePath}:
\${userInput}
\`\`\`
\${selectedText}
\`\`\`
Please provide a clear and concise explanation of what this code does, including:
1. The purpose and functionality
2. Key components and their interactions
3. Important patterns or techniques used
`
const FIX_TEMPLATE = `
Fix any issues in the following code from file path @/\${filePath}
\${diagnosticText}
\${userInput}
\`\`\`
\${selectedText}
\`\`\`
Please:
1. Address all detected problems listed above (if any)
2. Identify any other potential bugs or issues
3. Provide corrected code
4. Explain what was fixed and why
`
const IMPROVE_TEMPLATE = `
Improve the following code from file path @/\${filePath}:
\${userInput}
\`\`\`
\${selectedText}
\`\`\`
Please suggest improvements for:
1. Code readability and maintainability
2. Performance optimization
3. Best practices and patterns
4. Error handling and edge cases
Provide the improved code along with explanations for each enhancement.
`
// Get template based on prompt type
const defaultTemplates = {
EXPLAIN: EXPLAIN_TEMPLATE,
FIX: FIX_TEMPLATE,
IMPROVE: IMPROVE_TEMPLATE,
} as const
type CodeActionType = keyof typeof defaultTemplates
export const codeActionPrompt = {
default: defaultTemplates,
get: (customPrompts: Record<string, any> | undefined, type: CodeActionType): string => {
return customPrompts?.[type] ?? defaultTemplates[type]
},
create: (type: CodeActionType, params: PromptParams, customPrompts?: Record<string, any>): string => {
const template = codeActionPrompt.get(customPrompts, type)
return createPrompt(template, params)
},
} as const
export type { CodeActionType }
// User-friendly labels for code action types
export const codeActionLabels: Record<CodeActionType, string> = {
FIX: "Fix Issues",
EXPLAIN: "Explain Code",
IMPROVE: "Improve Code",
} as const

View File

@@ -8,14 +8,14 @@ import {
VSCodeCheckbox,
} from "@vscode/webview-ui-toolkit/react"
import { useExtensionState } from "../../context/ExtensionStateContext"
import { Mode, PromptComponent, getRoleDefinition, getAllModes, ModeConfig } from "../../../../src/shared/modes"
import {
Mode,
PromptComponent,
getRoleDefinition,
getAllModes,
ModeConfig,
enhancePrompt,
} from "../../../../src/shared/modes"
codeActionPrompt,
CodeActionType,
codeActionLabels,
} from "../../../../src/shared/support-prompt"
import { TOOL_GROUPS, GROUP_DISPLAY_NAMES, ToolGroup } from "../../../../src/shared/tool-groups"
import { vscode } from "../../utils/vscode"
@@ -50,11 +50,12 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
const [selectedPromptTitle, setSelectedPromptTitle] = useState("")
const [isToolsEditMode, setIsToolsEditMode] = useState(false)
const [isCreateModeDialogOpen, setIsCreateModeDialogOpen] = useState(false)
const [activeCodeActionTab, setActiveCodeActionTab] = useState<CodeActionType>("FIX")
// Direct update functions
const updateAgentPrompt = useCallback(
(mode: Mode, promptData: PromptComponent) => {
const existingPrompt = customPrompts?.[mode]
const existingPrompt = customPrompts?.[mode] as PromptComponent
const updatedPrompt = { ...existingPrompt, ...promptData }
// Only include properties that differ from defaults
@@ -256,8 +257,19 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
const updateEnhancePrompt = (value: string | undefined) => {
vscode.postMessage({
type: "updateEnhancedPrompt",
text: value,
type: "updateSupportPrompt",
values: {
enhance: value,
},
})
}
const updateCodeActionPrompt = (type: CodeActionType, value: string | undefined) => {
vscode.postMessage({
type: "updateSupportPrompt",
values: {
[type]: value,
},
})
}
@@ -271,7 +283,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
const handleAgentReset = (modeSlug: string) => {
// Only reset role definition for built-in modes
const existingPrompt = customPrompts?.[modeSlug]
const existingPrompt = customPrompts?.[modeSlug] as PromptComponent
updateAgentPrompt(modeSlug, {
...existingPrompt,
roleDefinition: undefined,
@@ -279,13 +291,27 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
}
const handleEnhanceReset = () => {
updateEnhancePrompt(undefined)
vscode.postMessage({
type: "resetSupportPrompt",
text: "enhance",
})
}
const handleCodeActionReset = (type: CodeActionType) => {
vscode.postMessage({
type: "resetSupportPrompt",
text: type,
})
}
const getEnhancePromptValue = (): string => {
return enhancePrompt.get(customPrompts)
}
const getCodeActionPromptValue = (type: CodeActionType): string => {
return codeActionPrompt.get(customPrompts, type)
}
const handleTestEnhancement = () => {
if (!testPrompt.trim()) return
@@ -563,7 +589,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
<VSCodeTextArea
value={(() => {
const customMode = findModeBySlug(mode, customModes)
const prompt = customPrompts?.[mode]
const prompt = customPrompts?.[mode] as PromptComponent
return customMode?.roleDefinition ?? prompt?.roleDefinition ?? getRoleDefinition(mode)
})()}
onChange={(e) => {
@@ -680,7 +706,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
<VSCodeTextArea
value={(() => {
const customMode = findModeBySlug(mode, customModes)
const prompt = customPrompts?.[mode]
const prompt = customPrompts?.[mode] as PromptComponent
return customMode?.customInstructions ?? prompt?.customInstructions ?? ""
})()}
onChange={(e) => {
@@ -696,7 +722,7 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
})
} else {
// For built-in modes, update the prompts
const existingPrompt = customPrompts?.[mode]
const existingPrompt = customPrompts?.[mode] as PromptComponent
updateAgentPrompt(mode, {
...existingPrompt,
customInstructions: value.trim() || undefined,
@@ -759,6 +785,77 @@ const PromptsView = ({ onDone }: PromptsViewProps) => {
</VSCodeButton>
</div>
<div style={{ marginBottom: "20px" }}>
<div style={{ fontWeight: "bold", marginBottom: "12px" }}>Code Action Prompts</div>
<div
style={{
display: "flex",
gap: "16px",
alignItems: "center",
marginBottom: "12px",
overflowX: "auto",
flexWrap: "nowrap",
paddingBottom: "4px",
paddingRight: "20px",
}}>
{Object.keys(codeActionPrompt.default).map((type) => (
<button
key={type}
data-testid={`${type}-tab`}
data-active={activeCodeActionTab === type ? "true" : "false"}
onClick={() => setActiveCodeActionTab(type as CodeActionType)}
style={{
padding: "4px 8px",
border: "none",
background:
activeCodeActionTab === type ? "var(--vscode-button-background)" : "none",
color:
activeCodeActionTab === type
? "var(--vscode-button-foreground)"
: "var(--vscode-foreground)",
cursor: "pointer",
opacity: activeCodeActionTab === type ? 1 : 0.8,
borderRadius: "3px",
fontWeight: "bold",
}}>
{codeActionLabels[type as CodeActionType]}
</button>
))}
</div>
{/* Show active tab content */}
<div key={activeCodeActionTab}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "4px",
}}>
<div style={{ fontWeight: "bold" }}>{activeCodeActionTab} Prompt</div>
<VSCodeButton
appearance="icon"
onClick={() => handleCodeActionReset(activeCodeActionTab)}
title={`Reset ${activeCodeActionTab} prompt to default`}>
<span className="codicon codicon-discard"></span>
</VSCodeButton>
</div>
<VSCodeTextArea
value={getCodeActionPromptValue(activeCodeActionTab)}
onChange={(e) => {
const value =
(e as CustomEvent)?.detail?.target?.value ||
((e as any).target as HTMLTextAreaElement).value
const trimmedValue = value.trim()
updateCodeActionPrompt(activeCodeActionTab, trimmedValue || undefined)
}}
rows={4}
resize="vertical"
style={{ width: "100%" }}
/>
</div>
</div>
<h3 style={{ color: "var(--vscode-foreground)", margin: "40px 0 20px 0" }}>Prompt Enhancement</h3>
<div