From 7b7de2b601b14d09e8e7aa25b3ee1183105c380c Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 27 Dec 2025 13:55:56 -0500 Subject: [PATCH] adding button to make when creating a new feature --- apps/ui/src/components/views/board-view.tsx | 24 +++++ .../board-view/dialogs/add-feature-dialog.tsx | 87 ++++++++++++++----- 2 files changed, 88 insertions(+), 23 deletions(-) diff --git a/apps/ui/src/components/views/board-view.tsx b/apps/ui/src/components/views/board-view.tsx index cfa063fd..01569cfe 100644 --- a/apps/ui/src/components/views/board-view.tsx +++ b/apps/ui/src/components/views/board-view.tsx @@ -523,6 +523,29 @@ export function BoardView() { [handleAddFeature, handleStartImplementation, defaultSkipTests] ); + // Handler for "Make" button - creates a feature and immediately starts it + const handleAddAndStartFeature = useCallback( + async (featureData: Parameters[0]) => { + await handleAddFeature(featureData); + + // Find the newly created feature and start it + setTimeout(async () => { + const latestFeatures = useAppStore.getState().features; + const newFeature = latestFeatures.find( + (f) => + f.status === 'backlog' && + f.description === featureData.description && + f.branchName === featureData.branchName + ); + + if (newFeature) { + await handleStartImplementation(newFeature); + } + }, FEATURE_CREATION_SETTLE_DELAY_MS); + }, + [handleAddFeature, handleStartImplementation] + ); + // Client-side auto mode: periodically check for backlog items and move them to in-progress // Use a ref to track the latest auto mode state so async operations always check the current value const autoModeRunningRef = useRef(autoMode.isRunning); @@ -1137,6 +1160,7 @@ export function BoardView() { } }} onAdd={handleAddFeature} + onAddAndStart={handleAddAndStartFeature} categorySuggestions={categorySuggestions} branchSuggestions={branchSuggestions} branchCardCounts={branchCardCounts} diff --git a/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx index a5eea2c5..47990a4e 100644 --- a/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx @@ -19,7 +19,14 @@ import { FeatureTextFilePath as DescriptionTextFilePath, ImagePreviewMap, } from '@/components/ui/description-image-dropzone'; -import { MessageSquare, Settings2, SlidersHorizontal, Sparkles, ChevronDown } from 'lucide-react'; +import { + MessageSquare, + Settings2, + SlidersHorizontal, + Sparkles, + ChevronDown, + Play, +} from 'lucide-react'; import { toast } from 'sonner'; import { getElectronAPI } from '@/lib/electron'; import { modelSupportsThinking } from '@/lib/utils'; @@ -55,25 +62,28 @@ import { type AncestorContext, } from '@automaker/dependency-resolver'; +type FeatureData = { + title: string; + category: string; + description: string; + images: FeatureImage[]; + imagePaths: DescriptionImagePath[]; + textFilePaths: DescriptionTextFilePath[]; + skipTests: boolean; + model: AgentModel; + thinkingLevel: ThinkingLevel; + branchName: string; // Can be empty string to use current branch + priority: number; + planningMode: PlanningMode; + requirePlanApproval: boolean; + dependencies?: string[]; +}; + interface AddFeatureDialogProps { open: boolean; onOpenChange: (open: boolean) => void; - onAdd: (feature: { - title: string; - category: string; - description: string; - images: FeatureImage[]; - imagePaths: DescriptionImagePath[]; - textFilePaths: DescriptionTextFilePath[]; - skipTests: boolean; - model: AgentModel; - thinkingLevel: ThinkingLevel; - branchName: string; // Can be empty string to use current branch - priority: number; - planningMode: PlanningMode; - requirePlanApproval: boolean; - dependencies?: string[]; - }) => void; + onAdd: (feature: FeatureData) => void; + onAddAndStart?: (feature: FeatureData) => void; categorySuggestions: string[]; branchSuggestions: string[]; branchCardCounts?: Record; // Map of branch name to unarchived card count @@ -92,6 +102,7 @@ export function AddFeatureDialog({ open, onOpenChange, onAdd, + onAddAndStart, categorySuggestions, branchSuggestions, branchCardCounts, @@ -188,16 +199,16 @@ export function AddFeatureDialog({ allFeatures, ]); - const handleAdd = () => { + const buildFeatureData = (): FeatureData | null => { if (!newFeature.description.trim()) { setDescriptionError(true); - return; + return null; } // Validate branch selection when "other branch" is selected if (useWorktrees && !useCurrentBranch && !newFeature.branchName.trim()) { toast.error('Please select a branch name'); - return; + return null; } const category = newFeature.category || 'Uncategorized'; @@ -235,7 +246,7 @@ export function AddFeatureDialog({ } } - onAdd({ + return { title: newFeature.title, category, description: finalDescription, @@ -251,9 +262,10 @@ export function AddFeatureDialog({ requirePlanApproval, // In spawn mode, automatically add parent as dependency dependencies: isSpawnMode && parentFeature ? [parentFeature.id] : undefined, - }); + }; + }; - // Reset form + const resetForm = () => { setNewFeature({ title: '', category: '', @@ -276,6 +288,24 @@ export function AddFeatureDialog({ onOpenChange(false); }; + const handleAdd = () => { + const featureData = buildFeatureData(); + if (!featureData) return; + + onAdd(featureData); + resetForm(); + }; + + const handleAddAndStart = () => { + if (!onAddAndStart) return; + + const featureData = buildFeatureData(); + if (!featureData) return; + + onAddAndStart(featureData); + resetForm(); + }; + const handleDialogClose = (open: boolean) => { onOpenChange(open); if (!open) { @@ -575,6 +605,17 @@ export function AddFeatureDialog({ + {onAddAndStart && ( + + )}