diff --git a/.automaker/feature_list.json b/.automaker/feature_list.json
index a958c15d..b6c2deb4 100644
--- a/.automaker/feature_list.json
+++ b/.automaker/feature_list.json
@@ -44,7 +44,7 @@
"category": "Kanban",
"description": "Add a way to force stop an agent on a card which is currently running",
"steps": [],
- "status": "in_progress"
+ "status": "verified"
},
{
"id": "feature-1765260864296-98yunv0vj",
diff --git a/app/src/components/views/kanban-card.tsx b/app/src/components/views/kanban-card.tsx
index 42a6705a..179fbc76 100644
--- a/app/src/components/views/kanban-card.tsx
+++ b/app/src/components/views/kanban-card.tsx
@@ -12,7 +12,7 @@ import {
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Feature } from "@/store/app-store";
-import { GripVertical, Edit, CheckCircle2, Circle, Loader2, Trash2, Eye, PlayCircle, RotateCcw } from "lucide-react";
+import { GripVertical, Edit, CheckCircle2, Circle, Loader2, Trash2, Eye, PlayCircle, RotateCcw, StopCircle } from "lucide-react";
interface KanbanCardProps {
feature: Feature;
@@ -21,11 +21,12 @@ interface KanbanCardProps {
onViewOutput?: () => void;
onVerify?: () => void;
onResume?: () => void;
+ onForceStop?: () => void;
hasContext?: boolean;
isCurrentAutoTask?: boolean;
}
-export function KanbanCard({ feature, onEdit, onDelete, onViewOutput, onVerify, onResume, hasContext, isCurrentAutoTask }: KanbanCardProps) {
+export function KanbanCard({ feature, onEdit, onDelete, onViewOutput, onVerify, onResume, onForceStop, hasContext, isCurrentAutoTask }: KanbanCardProps) {
// Disable dragging if the feature is in progress or verified
const isDraggable = feature.status === "backlog";
const {
@@ -112,20 +113,39 @@ export function KanbanCard({ feature, onEdit, onDelete, onViewOutput, onVerify,
{/* Actions */}
- {isCurrentAutoTask && onViewOutput && (
-
+ {isCurrentAutoTask && (
+ <>
+ {onViewOutput && (
+
+ )}
+ {onForceStop && (
+
+ )}
+ >
)}
{!isCurrentAutoTask && feature.status === "in_progress" && (
<>
diff --git a/app/src/hooks/use-auto-mode.ts b/app/src/hooks/use-auto-mode.ts
index b86bdb3f..4d1e678c 100644
--- a/app/src/hooks/use-auto-mode.ts
+++ b/app/src/hooks/use-auto-mode.ts
@@ -180,6 +180,35 @@ export function useAutoMode() {
}
}, [setAutoModeRunning, clearRunningTasks]);
+ // Stop a specific feature
+ const stopFeature = useCallback(async (featureId: string) => {
+ try {
+ const api = getElectronAPI();
+ if (!api?.autoMode?.stopFeature) {
+ throw new Error("Stop feature API not available");
+ }
+
+ const result = await api.autoMode.stopFeature(featureId);
+
+ if (result.success) {
+ removeRunningTask(featureId);
+ console.log("[AutoMode] Feature stopped successfully:", featureId);
+ addAutoModeActivity({
+ featureId,
+ type: "complete",
+ message: "Feature stopped by user",
+ passes: false,
+ });
+ } else {
+ console.error("[AutoMode] Failed to stop feature:", result.error);
+ throw new Error(result.error || "Failed to stop feature");
+ }
+ } catch (error) {
+ console.error("[AutoMode] Error stopping feature:", error);
+ throw error;
+ }
+ }, [removeRunningTask, addAutoModeActivity]);
+
return {
isRunning: isAutoModeRunning,
runningTasks: runningAutoTasks,
@@ -187,5 +216,6 @@ export function useAutoMode() {
canStartNewTask,
start,
stop,
+ stopFeature,
};
}
diff --git a/app/src/types/electron.d.ts b/app/src/types/electron.d.ts
index f65d68c8..1756831f 100644
--- a/app/src/types/electron.d.ts
+++ b/app/src/types/electron.d.ts
@@ -208,10 +208,16 @@ export interface AutoModeAPI {
error?: string;
}>;
+ stopFeature: (featureId: string) => Promise<{
+ success: boolean;
+ error?: string;
+ }>;
+
status: () => Promise<{
success: boolean;
isRunning?: boolean;
currentFeatureId?: string | null;
+ runningFeatures?: string[];
error?: string;
}>;