mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 08:53:36 +00:00
Add force stop feature for running agents on kanban cards
This commit is contained in:
@@ -44,7 +44,7 @@
|
|||||||
"category": "Kanban",
|
"category": "Kanban",
|
||||||
"description": "Add a way to force stop an agent on a card which is currently running",
|
"description": "Add a way to force stop an agent on a card which is currently running",
|
||||||
"steps": [],
|
"steps": [],
|
||||||
"status": "in_progress"
|
"status": "verified"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "feature-1765260864296-98yunv0vj",
|
"id": "feature-1765260864296-98yunv0vj",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Feature } from "@/store/app-store";
|
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 {
|
interface KanbanCardProps {
|
||||||
feature: Feature;
|
feature: Feature;
|
||||||
@@ -21,11 +21,12 @@ interface KanbanCardProps {
|
|||||||
onViewOutput?: () => void;
|
onViewOutput?: () => void;
|
||||||
onVerify?: () => void;
|
onVerify?: () => void;
|
||||||
onResume?: () => void;
|
onResume?: () => void;
|
||||||
|
onForceStop?: () => void;
|
||||||
hasContext?: boolean;
|
hasContext?: boolean;
|
||||||
isCurrentAutoTask?: 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
|
// Disable dragging if the feature is in progress or verified
|
||||||
const isDraggable = feature.status === "backlog";
|
const isDraggable = feature.status === "backlog";
|
||||||
const {
|
const {
|
||||||
@@ -112,20 +113,39 @@ export function KanbanCard({ feature, onEdit, onDelete, onViewOutput, onVerify,
|
|||||||
|
|
||||||
{/* Actions */}
|
{/* Actions */}
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{isCurrentAutoTask && onViewOutput && (
|
{isCurrentAutoTask && (
|
||||||
<Button
|
<>
|
||||||
variant="default"
|
{onViewOutput && (
|
||||||
size="sm"
|
<Button
|
||||||
className="flex-1 h-7 text-xs bg-purple-600 hover:bg-purple-700"
|
variant="default"
|
||||||
onClick={(e) => {
|
size="sm"
|
||||||
e.stopPropagation();
|
className="flex-1 h-7 text-xs bg-purple-600 hover:bg-purple-700"
|
||||||
onViewOutput();
|
onClick={(e) => {
|
||||||
}}
|
e.stopPropagation();
|
||||||
data-testid={`view-output-${feature.id}`}
|
onViewOutput();
|
||||||
>
|
}}
|
||||||
<Eye className="w-3 h-3 mr-1" />
|
data-testid={`view-output-${feature.id}`}
|
||||||
View Output
|
>
|
||||||
</Button>
|
<Eye className="w-3 h-3 mr-1" />
|
||||||
|
View Output
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{onForceStop && (
|
||||||
|
<Button
|
||||||
|
variant="destructive"
|
||||||
|
size="sm"
|
||||||
|
className="h-7 text-xs"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onForceStop();
|
||||||
|
}}
|
||||||
|
data-testid={`force-stop-${feature.id}`}
|
||||||
|
>
|
||||||
|
<StopCircle className="w-3 h-3 mr-1" />
|
||||||
|
Stop
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{!isCurrentAutoTask && feature.status === "in_progress" && (
|
{!isCurrentAutoTask && feature.status === "in_progress" && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -180,6 +180,35 @@ export function useAutoMode() {
|
|||||||
}
|
}
|
||||||
}, [setAutoModeRunning, clearRunningTasks]);
|
}, [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 {
|
return {
|
||||||
isRunning: isAutoModeRunning,
|
isRunning: isAutoModeRunning,
|
||||||
runningTasks: runningAutoTasks,
|
runningTasks: runningAutoTasks,
|
||||||
@@ -187,5 +216,6 @@ export function useAutoMode() {
|
|||||||
canStartNewTask,
|
canStartNewTask,
|
||||||
start,
|
start,
|
||||||
stop,
|
stop,
|
||||||
|
stopFeature,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
6
app/src/types/electron.d.ts
vendored
6
app/src/types/electron.d.ts
vendored
@@ -208,10 +208,16 @@ export interface AutoModeAPI {
|
|||||||
error?: string;
|
error?: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
stopFeature: (featureId: string) => Promise<{
|
||||||
|
success: boolean;
|
||||||
|
error?: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
status: () => Promise<{
|
status: () => Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
isRunning?: boolean;
|
isRunning?: boolean;
|
||||||
currentFeatureId?: string | null;
|
currentFeatureId?: string | null;
|
||||||
|
runningFeatures?: string[];
|
||||||
error?: string;
|
error?: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user