diff --git a/app/electron/auto-mode-service.js b/app/electron/auto-mode-service.js index f010e7a1..a39ba88f 100644 --- a/app/electron/auto-mode-service.js +++ b/app/electron/auto-mode-service.js @@ -557,6 +557,21 @@ class AutoModeService { execution.sendToRenderer = sendToRenderer; this.runningFeatures.set(featureId, execution); + // Start the async work in the background (don't await) + // This allows the API to return immediately so the modal can close + this.runFollowUpWork({ projectPath, featureId, prompt, imagePaths, sendToRenderer, execution }).catch((error) => { + console.error("[AutoMode] Follow-up work error:", error); + this.runningFeatures.delete(featureId); + }); + + // Return immediately so the frontend can close the modal + return { success: true }; + } + + /** + * Internal method to run follow-up work asynchronously + */ + async runFollowUpWork({ projectPath, featureId, prompt, imagePaths, sendToRenderer, execution }) { try { // Load features const features = await featureLoader.loadFeatures(projectPath); @@ -611,8 +626,6 @@ class AutoModeService { passes: result.passes, message: result.message, }); - - return { success: true, passes: result.passes }; } catch (error) { console.error("[AutoMode] Error in follow-up:", error); sendToRenderer({ @@ -620,7 +633,6 @@ class AutoModeService { error: error.message, featureId: featureId, }); - throw error; } finally { this.runningFeatures.delete(featureId); } diff --git a/app/src/components/views/board-view.tsx b/app/src/components/views/board-view.tsx index 705030cf..82c1ba4e 100644 --- a/app/src/components/views/board-view.tsx +++ b/app/src/components/views/board-view.tsx @@ -706,56 +706,55 @@ export function BoardView() { const handleSendFollowUp = async () => { if (!currentProject || !followUpFeature || !followUpPrompt.trim()) return; + // Save values before clearing state + const featureId = followUpFeature.id; + const featureDescription = followUpFeature.description; + const prompt = followUpPrompt; + const imagePaths = followUpImagePaths.map(img => img.path); + console.log("[Board] Sending follow-up prompt for feature:", { - id: followUpFeature.id, - prompt: followUpPrompt, - imagePaths: followUpImagePaths + id: featureId, + prompt: prompt, + imagePaths: imagePaths }); - try { - const api = getElectronAPI(); - if (!api?.autoMode?.followUpFeature) { - console.error("Follow-up feature API not available"); - toast.error("Follow-up not available", { - description: "This feature is not available in the current version.", - }); - return; - } + const api = getElectronAPI(); + if (!api?.autoMode?.followUpFeature) { + console.error("Follow-up feature API not available"); + toast.error("Follow-up not available", { + description: "This feature is not available in the current version.", + }); + return; + } - // Move feature back to in_progress before sending follow-up - updateFeature(followUpFeature.id, { status: "in_progress", startedAt: new Date().toISOString() }); + // Move feature back to in_progress before sending follow-up + updateFeature(featureId, { status: "in_progress", startedAt: new Date().toISOString() }); - // Call the API to send follow-up prompt - const result = await api.autoMode.followUpFeature( - currentProject.path, - followUpFeature.id, - followUpPrompt, - followUpImagePaths.map(img => img.path) - ); + // Reset follow-up state immediately (close dialog, clear form) + setShowFollowUpDialog(false); + setFollowUpFeature(null); + setFollowUpPrompt(""); + setFollowUpImagePaths([]); - if (result.success) { - console.log("[Board] Follow-up started successfully"); - toast.success("Follow-up started", { - description: `Continuing work on: ${followUpFeature.description.slice(0, 50)}${followUpFeature.description.length > 50 ? "..." : ""}`, - }); - setShowFollowUpDialog(false); - setFollowUpFeature(null); - setFollowUpPrompt(""); - setFollowUpImagePaths([]); - } else { - console.error("[Board] Failed to send follow-up:", result.error); - toast.error("Failed to send follow-up", { - description: result.error || "An error occurred", - }); - await loadFeatures(); - } - } catch (error) { + // Show success toast immediately + toast.success("Follow-up started", { + description: `Continuing work on: ${featureDescription.slice(0, 50)}${featureDescription.length > 50 ? "..." : ""}`, + }); + + // Call the API in the background (don't await - let it run async) + api.autoMode.followUpFeature( + currentProject.path, + featureId, + prompt, + imagePaths + ).catch((error) => { console.error("[Board] Error sending follow-up:", error); toast.error("Failed to send follow-up", { description: error instanceof Error ? error.message : "An error occurred", }); - await loadFeatures(); - } + // Reload features to revert status if there was an error + loadFeatures(); + }); }; // Handle commit-only for waiting_approval features (marks as verified and commits) diff --git a/app/src/lib/electron.ts b/app/src/lib/electron.ts index 514e8f47..91bb6854 100644 --- a/app/src/lib/electron.ts +++ b/app/src/lib/electron.ts @@ -585,9 +585,11 @@ function createMockAutoModeAPI(): AutoModeAPI { mockRunningFeatures.add(featureId); // Simulate follow-up work (similar to run but with additional context) + // Note: We don't await this - it runs in the background like the real implementation simulateAutoModeLoop(projectPath, featureId); - return { success: true, passes: true }; + // Return immediately so the modal can close (matches real implementation) + return { success: true }; }, commitFeature: async (projectPath: string, featureId: string) => {