refactor: streamline feature creation and auto-start logic in BoardView

- Removed the delay mechanism for starting newly created features, simplifying the process.
- Updated the logic to capture existing feature IDs before adding a new feature, allowing for immediate identification of the newly created feature.
- Enhanced error handling to notify users if the feature could not be started automatically.
This commit is contained in:
Test User
2025-12-27 14:20:52 -05:00
parent 7b7de2b601
commit 01911287f2
2 changed files with 46 additions and 54 deletions

View File

@@ -60,9 +60,6 @@ import {
// Stable empty array to avoid infinite loop in selector // Stable empty array to avoid infinite loop in selector
const EMPTY_WORKTREES: ReturnType<ReturnType<typeof useAppStore.getState>['getWorktrees']> = []; const EMPTY_WORKTREES: ReturnType<ReturnType<typeof useAppStore.getState>['getWorktrees']> = [];
/** Delay before starting a newly created feature to allow state to settle */
const FEATURE_CREATION_SETTLE_DELAY_MS = 500;
export function BoardView() { export function BoardView() {
const { const {
currentProject, currentProject,
@@ -461,23 +458,22 @@ export function BoardView() {
requirePlanApproval: false, requirePlanApproval: false,
}; };
// Capture existing feature IDs before adding
const featuresBeforeIds = new Set(useAppStore.getState().features.map((f) => f.id));
await handleAddFeature(featureData); await handleAddFeature(featureData);
// Find the newly created feature and start it // Find the newly created feature by looking for an ID that wasn't in the original set
// We need to wait a moment for the feature to be created const latestFeatures = useAppStore.getState().features;
setTimeout(async () => { const newFeature = latestFeatures.find((f) => !featuresBeforeIds.has(f.id));
const latestFeatures = useAppStore.getState().features;
const newFeature = latestFeatures.find(
(f) =>
f.branchName === worktree.branch &&
f.status === 'backlog' &&
f.description.includes(`PR #${prNumber}`)
);
if (newFeature) { if (newFeature) {
await handleStartImplementation(newFeature); await handleStartImplementation(newFeature);
} } else {
}, FEATURE_CREATION_SETTLE_DELAY_MS); 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] [handleAddFeature, handleStartImplementation, defaultSkipTests]
); );
@@ -503,22 +499,22 @@ export function BoardView() {
requirePlanApproval: false, requirePlanApproval: false,
}; };
// Capture existing feature IDs before adding
const featuresBeforeIds = new Set(useAppStore.getState().features.map((f) => f.id));
await handleAddFeature(featureData); await handleAddFeature(featureData);
// Find the newly created feature and start it // Find the newly created feature by looking for an ID that wasn't in the original set
setTimeout(async () => { const latestFeatures = useAppStore.getState().features;
const latestFeatures = useAppStore.getState().features; const newFeature = latestFeatures.find((f) => !featuresBeforeIds.has(f.id));
const newFeature = latestFeatures.find(
(f) =>
f.branchName === worktree.branch &&
f.status === 'backlog' &&
f.description.includes('Pull latest from origin/main')
);
if (newFeature) { if (newFeature) {
await handleStartImplementation(newFeature); await handleStartImplementation(newFeature);
} } else {
}, FEATURE_CREATION_SETTLE_DELAY_MS); 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] [handleAddFeature, handleStartImplementation, defaultSkipTests]
); );
@@ -526,22 +522,22 @@ export function BoardView() {
// Handler for "Make" button - creates a feature and immediately starts it // Handler for "Make" button - creates a feature and immediately starts it
const handleAddAndStartFeature = useCallback( const handleAddAndStartFeature = useCallback(
async (featureData: Parameters<typeof handleAddFeature>[0]) => { async (featureData: Parameters<typeof handleAddFeature>[0]) => {
// Capture existing feature IDs before adding
const featuresBeforeIds = new Set(useAppStore.getState().features.map((f) => f.id));
await handleAddFeature(featureData); await handleAddFeature(featureData);
// Find the newly created feature and start it // Find the newly created feature by looking for an ID that wasn't in the original set
setTimeout(async () => { const latestFeatures = useAppStore.getState().features;
const latestFeatures = useAppStore.getState().features; const newFeature = latestFeatures.find((f) => !featuresBeforeIds.has(f.id));
const newFeature = latestFeatures.find(
(f) =>
f.status === 'backlog' &&
f.description === featureData.description &&
f.branchName === featureData.branchName
);
if (newFeature) { if (newFeature) {
await handleStartImplementation(newFeature); await handleStartImplementation(newFeature);
} } else {
}, FEATURE_CREATION_SETTLE_DELAY_MS); 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] [handleAddFeature, handleStartImplementation]
); );

View File

@@ -288,24 +288,20 @@ export function AddFeatureDialog({
onOpenChange(false); onOpenChange(false);
}; };
const handleAdd = () => { const handleAction = (actionFn?: (data: FeatureData) => void) => {
const featureData = buildFeatureData(); if (!actionFn) return;
if (!featureData) return;
onAdd(featureData);
resetForm();
};
const handleAddAndStart = () => {
if (!onAddAndStart) return;
const featureData = buildFeatureData(); const featureData = buildFeatureData();
if (!featureData) return; if (!featureData) return;
onAddAndStart(featureData); actionFn(featureData);
resetForm(); resetForm();
}; };
const handleAdd = () => handleAction(onAdd);
const handleAddAndStart = () => handleAction(onAddAndStart);
const handleDialogClose = (open: boolean) => { const handleDialogClose = (open: boolean) => {
onOpenChange(open); onOpenChange(open);
if (!open) { if (!open) {