diff --git a/apps/ui/src/components/views/board-view.tsx b/apps/ui/src/components/views/board-view.tsx index 01569cfe..0541de9f 100644 --- a/apps/ui/src/components/views/board-view.tsx +++ b/apps/ui/src/components/views/board-view.tsx @@ -60,9 +60,6 @@ import { // Stable empty array to avoid infinite loop in selector const EMPTY_WORKTREES: ReturnType['getWorktrees']> = []; -/** Delay before starting a newly created feature to allow state to settle */ -const FEATURE_CREATION_SETTLE_DELAY_MS = 500; - export function BoardView() { const { currentProject, @@ -461,23 +458,22 @@ export function BoardView() { requirePlanApproval: false, }; + // Capture existing feature IDs before adding + const featuresBeforeIds = new Set(useAppStore.getState().features.map((f) => f.id)); await handleAddFeature(featureData); - // Find the newly created feature and start it - // We need to wait a moment for the feature to be created - setTimeout(async () => { - const latestFeatures = useAppStore.getState().features; - const newFeature = latestFeatures.find( - (f) => - f.branchName === worktree.branch && - f.status === 'backlog' && - f.description.includes(`PR #${prNumber}`) - ); + // Find the newly created feature by looking for an ID that wasn't in the original set + const latestFeatures = useAppStore.getState().features; + const newFeature = latestFeatures.find((f) => !featuresBeforeIds.has(f.id)); - if (newFeature) { - await handleStartImplementation(newFeature); - } - }, FEATURE_CREATION_SETTLE_DELAY_MS); + if (newFeature) { + await handleStartImplementation(newFeature); + } else { + console.error('Could not find newly created feature to start it automatically.'); + toast.error('Failed to auto-start feature', { + description: 'The feature was created but could not be started automatically.', + }); + } }, [handleAddFeature, handleStartImplementation, defaultSkipTests] ); @@ -503,22 +499,22 @@ export function BoardView() { requirePlanApproval: false, }; + // Capture existing feature IDs before adding + const featuresBeforeIds = new Set(useAppStore.getState().features.map((f) => f.id)); await handleAddFeature(featureData); - // Find the newly created feature and start it - setTimeout(async () => { - const latestFeatures = useAppStore.getState().features; - const newFeature = latestFeatures.find( - (f) => - f.branchName === worktree.branch && - f.status === 'backlog' && - f.description.includes('Pull latest from origin/main') - ); + // Find the newly created feature by looking for an ID that wasn't in the original set + const latestFeatures = useAppStore.getState().features; + const newFeature = latestFeatures.find((f) => !featuresBeforeIds.has(f.id)); - if (newFeature) { - await handleStartImplementation(newFeature); - } - }, FEATURE_CREATION_SETTLE_DELAY_MS); + if (newFeature) { + await handleStartImplementation(newFeature); + } else { + console.error('Could not find newly created feature to start it automatically.'); + toast.error('Failed to auto-start feature', { + description: 'The feature was created but could not be started automatically.', + }); + } }, [handleAddFeature, handleStartImplementation, defaultSkipTests] ); @@ -526,22 +522,22 @@ export function BoardView() { // Handler for "Make" button - creates a feature and immediately starts it const handleAddAndStartFeature = useCallback( async (featureData: Parameters[0]) => { + // Capture existing feature IDs before adding + const featuresBeforeIds = new Set(useAppStore.getState().features.map((f) => f.id)); 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 - ); + // Find the newly created feature by looking for an ID that wasn't in the original set + const latestFeatures = useAppStore.getState().features; + const newFeature = latestFeatures.find((f) => !featuresBeforeIds.has(f.id)); - if (newFeature) { - await handleStartImplementation(newFeature); - } - }, FEATURE_CREATION_SETTLE_DELAY_MS); + if (newFeature) { + await handleStartImplementation(newFeature); + } else { + console.error('Could not find newly created feature to start it automatically.'); + toast.error('Failed to auto-start feature', { + description: 'The feature was created but could not be started automatically.', + }); + } }, [handleAddFeature, handleStartImplementation] ); 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 47990a4e..35a95e91 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 @@ -288,24 +288,20 @@ export function AddFeatureDialog({ onOpenChange(false); }; - const handleAdd = () => { - const featureData = buildFeatureData(); - if (!featureData) return; - - onAdd(featureData); - resetForm(); - }; - - const handleAddAndStart = () => { - if (!onAddAndStart) return; + const handleAction = (actionFn?: (data: FeatureData) => void) => { + if (!actionFn) return; const featureData = buildFeatureData(); if (!featureData) return; - onAddAndStart(featureData); + actionFn(featureData); resetForm(); }; + const handleAdd = () => handleAction(onAdd); + + const handleAddAndStart = () => handleAction(onAddAndStart); + const handleDialogClose = (open: boolean) => { onOpenChange(open); if (!open) {