From ffbd8fed748ff4b60c53ee6ac54d7cf0548a7048 Mon Sep 17 00:00:00 2001
From: soryu <soryu@soryu.co>
Date: Thu, 12 Feb 2026 03:04:26 +0000
Subject: Add task cleanup and directive PR updating

---
 .../src/components/directives/DirectiveDetail.tsx     | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

(limited to 'makima/frontend/src/components/directives/DirectiveDetail.tsx')

diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx
index ab6ddbb..332a417 100644
--- a/makima/frontend/src/components/directives/DirectiveDetail.tsx
+++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx
@@ -34,6 +34,7 @@ interface DirectiveDetailProps {
   onUpdateGoal: (goal: string) => void;
   onDelete: () => void;
   onRefresh: () => void;
+  onCleanupTasks: () => void;
 }
 
 export function DirectiveDetail({
@@ -47,6 +48,7 @@ export function DirectiveDetail({
   onUpdateGoal,
   onDelete,
   onRefresh,
+  onCleanupTasks,
 }: DirectiveDetailProps) {
   const [editingGoal, setEditingGoal] = useState(false);
   const [goalText, setGoalText] = useState(directive.goal);
@@ -59,6 +61,8 @@ export function DirectiveDetail({
   const completedSteps = directive.steps.filter((s) => s.status === "completed").length;
   const totalSteps = directive.steps.length;
   const progress = totalSteps > 0 ? Math.round((completedSteps / totalSteps) * 100) : 0;
+  const terminalStatuses = new Set(["completed", "failed", "skipped"]);
+  const hasTerminalTasks = directive.steps.some((s) => s.taskId && terminalStatuses.has(s.status));
 
   // Memory panel state
   const [memoryOpen, setMemoryOpen] = useState(false);
@@ -221,11 +225,11 @@ export function DirectiveDetail({
         )}
 
         {/* Completion task indicator */}
-        {directive.completionTaskId && !directive.prUrl && (
+        {directive.completionTaskId && (
           <div className="flex items-center gap-2 mb-2 px-2 py-1.5 bg-[#1a1a10] border border-yellow-900 rounded">
             <span className="inline-block w-2 h-2 rounded-full bg-yellow-400 animate-pulse" />
             <span className="text-[10px] font-mono text-yellow-400">
-              Creating PR...
+              {directive.prUrl ? "Updating PR..." : "Creating PR..."}
             </span>
             <a
               href={`/mesh/${directive.completionTaskId}`}
@@ -279,10 +283,19 @@ export function DirectiveDetail({
               </button>
             </div>
           )}
+          {hasTerminalTasks && (
+            <button
+              type="button"
+              onClick={onCleanupTasks}
+              className="text-[10px] font-mono text-[#7788aa] hover:text-white border border-[#2a3a5a] rounded px-2 py-1 ml-auto"
+            >
+              Clean up tasks
+            </button>
+          )}
           <button
             type="button"
             onClick={onDelete}
-            className="text-[10px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-2 py-1 ml-auto"
+            className={`text-[10px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-2 py-1 ${hasTerminalTasks ? "" : "ml-auto"}`}
           >
             Delete
           </button>
-- 
cgit v1.2.3

