From 1abf21923051342377a2292c6356b4fd43c9b579 Mon Sep 17 00:00:00 2001 From: Shirone Date: Thu, 15 Jan 2026 21:00:32 +0100 Subject: [PATCH] refactor: create reusable PromptTabContent component and add {{count}} placeholder - Create PromptTabContent reusable component in prompt-customization-section.tsx - Update all tabs (Agent, Commit Message, Title Generation, Ideation, App Spec, Context Description, Suggestions, Task Execution) to use the new component - Add {{count}} placeholder to DEFAULT_SUGGESTIONS_SYSTEM_PROMPT for dynamic suggestion count Addresses PR review comments from Gemini. Co-Authored-By: Claude Opus 4.5 --- .../prompts/prompt-customization-section.tsx | 700 ++++++++---------- libs/prompts/src/defaults.ts | 2 +- 2 files changed, 326 insertions(+), 376 deletions(-) diff --git a/apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx b/apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx index a6b9bf44..c0a7308e 100644 --- a/apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx +++ b/apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx @@ -65,6 +65,44 @@ function calculateMinHeight(text: string): string { return `${minHeight}px`; } +/** + * PromptTabContent Component + * + * Reusable container for prompt customization tabs. + * Provides consistent header with title and reset button. + */ +interface PromptTabContentProps { + value: string; + title: string; + category: keyof PromptCustomization; + onReset: (category: keyof PromptCustomization) => void; + children: React.ReactNode; + infoBanner?: React.ReactNode; +} + +function PromptTabContent({ + value, + title, + category, + onReset, + children, + infoBanner, +}: PromptTabContentProps) { + return ( + +
+

{title}

+ +
+ {infoBanner} +
{children}
+
+ ); +} + /** * PromptField Component * @@ -423,30 +461,20 @@ export function PromptCustomizationSection({ {/* Agent Tab */} - -
-

Agent Runner Prompts

- -
- -
- updatePrompt('agent', 'systemPrompt', value)} - /> -
-
+ + updatePrompt('agent', 'systemPrompt', value)} + /> + {/* Backlog Plan Tab */} @@ -569,60 +597,38 @@ export function PromptCustomizationSection({ {/* Commit Message Tab */} - -
-

Commit Message Prompts

- -
- -
- - updatePrompt('commitMessage', 'systemPrompt', value) - } - /> -
-
+ + updatePrompt('commitMessage', 'systemPrompt', value)} + /> + {/* Title Generation Tab */} - -
-

Title Generation Prompts

- -
- -
- - updatePrompt('titleGeneration', 'systemPrompt', value) - } - /> -
-
+ + + updatePrompt('titleGeneration', 'systemPrompt', value) + } + /> + {/* Issue Validation Tab */} @@ -667,330 +673,274 @@ export function PromptCustomizationSection({ {/* Ideation Tab */} - -
-

Ideation Prompts

- -
+ + + updatePrompt('ideation', 'ideationSystemPrompt', value) + } + /> -
- - updatePrompt('ideation', 'ideationSystemPrompt', value) - } - /> - - - updatePrompt('ideation', 'suggestionsSystemPrompt', value) - } - critical={true} - /> -
-
+ + updatePrompt('ideation', 'suggestionsSystemPrompt', value) + } + critical={true} + /> + {/* App Spec Tab */} - -
-

App Specification Prompts

- -
+ + + updatePrompt('appSpec', 'generateSpecSystemPrompt', value) + } + /> -
- - updatePrompt('appSpec', 'generateSpecSystemPrompt', value) - } - /> + + updatePrompt('appSpec', 'structuredSpecInstructions', value) + } + critical={true} + /> - - updatePrompt('appSpec', 'structuredSpecInstructions', value) - } - critical={true} - /> - - - updatePrompt('appSpec', 'generateFeaturesFromSpecPrompt', value) - } - critical={true} - /> -
-
+ + updatePrompt('appSpec', 'generateFeaturesFromSpecPrompt', value) + } + critical={true} + /> + {/* Context Description Tab */} - -
-

Context Description Prompts

- -
+ + + updatePrompt('contextDescription', 'describeFilePrompt', value) + } + /> -
- - updatePrompt('contextDescription', 'describeFilePrompt', value) - } - /> - - - updatePrompt('contextDescription', 'describeImagePrompt', value) - } - /> -
-
+ + updatePrompt('contextDescription', 'describeImagePrompt', value) + } + /> + {/* Suggestions Tab */} - -
-

Suggestions Prompts

- -
+ + updatePrompt('suggestions', 'featuresPrompt', value)} + /> -
- - updatePrompt('suggestions', 'featuresPrompt', value) - } - /> + + updatePrompt('suggestions', 'refactoringPrompt', value) + } + /> - - updatePrompt('suggestions', 'refactoringPrompt', value) - } - /> + updatePrompt('suggestions', 'securityPrompt', value)} + /> - - updatePrompt('suggestions', 'securityPrompt', value) - } - /> + + updatePrompt('suggestions', 'performancePrompt', value) + } + /> - - updatePrompt('suggestions', 'performancePrompt', value) - } - /> - - updatePrompt('suggestions', 'baseTemplate', value)} - /> -
-
+ updatePrompt('suggestions', 'baseTemplate', value)} + /> + {/* Task Execution Tab */} - -
-

Task Execution Prompts

- -
- - {/* Info Banner for Task Execution */} -
- -
-

Template Variables

-

- Task execution prompts use Handlebars syntax for variable substitution. Variables - include{' '} - {'{{taskId}}'},{' '} - - {'{{taskDescription}}'} - - ,{' '} - - {'{{completedTasks}}'} - - , etc. -

+ + +
+

Template Variables

+

+ Task execution prompts use Handlebars syntax for variable substitution. + Variables include{' '} + {'{{taskId}}'},{' '} + + {'{{taskDescription}}'} + + ,{' '} + + {'{{completedTasks}}'} + + , etc. +

+
-
+ } + > + + updatePrompt('taskExecution', 'taskPromptTemplate', value) + } + /> -
- - updatePrompt('taskExecution', 'taskPromptTemplate', value) - } - /> + + updatePrompt('taskExecution', 'implementationInstructions', value) + } + /> - - updatePrompt('taskExecution', 'implementationInstructions', value) - } - /> + + updatePrompt('taskExecution', 'playwrightVerificationInstructions', value) + } + /> - - updatePrompt('taskExecution', 'playwrightVerificationInstructions', value) - } - /> + + updatePrompt('taskExecution', 'learningExtractionSystemPrompt', value) + } + critical={true} + /> - - updatePrompt('taskExecution', 'learningExtractionSystemPrompt', value) - } - critical={true} - /> + + updatePrompt('taskExecution', 'learningExtractionUserPromptTemplate', value) + } + critical={true} + /> - - updatePrompt('taskExecution', 'learningExtractionUserPromptTemplate', value) - } - critical={true} - /> + + updatePrompt('taskExecution', 'planRevisionTemplate', value) + } + /> - - updatePrompt('taskExecution', 'planRevisionTemplate', value) - } - /> + + updatePrompt('taskExecution', 'continuationAfterApprovalTemplate', value) + } + /> - - updatePrompt('taskExecution', 'continuationAfterApprovalTemplate', value) - } - /> + + updatePrompt('taskExecution', 'resumeFeatureTemplate', value) + } + /> - - updatePrompt('taskExecution', 'resumeFeatureTemplate', value) - } - /> - - - updatePrompt('taskExecution', 'projectAnalysisPrompt', value) - } - /> -
-
+ + updatePrompt('taskExecution', 'projectAnalysisPrompt', value) + } + /> + diff --git a/libs/prompts/src/defaults.ts b/libs/prompts/src/defaults.ts index 27aa332e..a582313d 100644 --- a/libs/prompts/src/defaults.ts +++ b/libs/prompts/src/defaults.ts @@ -604,7 +604,7 @@ IMPORTANT: You do NOT have access to any tools. You CANNOT read files, search co You must generate suggestions based ONLY on the project context provided below. Do NOT say "I'll analyze" or "Let me explore" - you cannot do those things. -Based on the project context and the user's prompt, generate creative and actionable feature suggestions. +Based on the project context and the user's prompt, generate exactly {{count}} creative and actionable feature suggestions. YOUR RESPONSE MUST BE ONLY A JSON ARRAY - nothing else. No explanation, no preamble, no markdown code fences.