From 00b02e12a4ffe40c60f180fe742f090873a2f698 Mon Sep 17 00:00:00 2001
From: soryu <soryu@soryu.co>
Date: Sat, 7 Mar 2026 20:16:54 +0000
Subject: feat: soryu-co/soryu - makima: Add right-click context menu to
 directives page

---
 makima/frontend/src/routes/directives.tsx | 50 +++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

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

diff --git a/makima/frontend/src/routes/directives.tsx b/makima/frontend/src/routes/directives.tsx
index cee4920..f1b430d 100644
--- a/makima/frontend/src/routes/directives.tsx
+++ b/makima/frontend/src/routes/directives.tsx
@@ -5,13 +5,13 @@ import { DirectiveList } from "../components/directives/DirectiveList";
 import { DirectiveDetail } from "../components/directives/DirectiveDetail";
 import { useDirectives, useDirective } from "../hooks/useDirectives";
 import { useAuth } from "../contexts/AuthContext";
-import { getRepositorySuggestions, type RepositoryHistoryEntry } from "../lib/api";
+import { getRepositorySuggestions, startDirective, pauseDirective, updateDirective, type RepositoryHistoryEntry, type DirectiveSummary } from "../lib/api";
 
 export default function DirectivesPage() {
   const { isAuthenticated, isAuthConfigured, isLoading: authLoading } = useAuth();
   const navigate = useNavigate();
   const { id: selectedId } = useParams<{ id: string }>();
-  const { directives, loading: listLoading, create, remove } = useDirectives();
+  const { directives, loading: listLoading, create, remove, refresh: refreshList } = useDirectives();
   const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanup, pickUpOrders, createPR } = useDirective(selectedId);
 
   const [showCreate, setShowCreate] = useState(false);
@@ -66,6 +66,47 @@ export default function DirectivesPage() {
     );
   }
 
+  const handleContextStart = async (directive: DirectiveSummary) => {
+    try {
+      await startDirective(directive.id);
+      await refreshList();
+    } catch (e) {
+      console.error("Failed to start directive:", e);
+    }
+  };
+
+  const handleContextPause = async (directive: DirectiveSummary) => {
+    try {
+      await pauseDirective(directive.id);
+      await refreshList();
+    } catch (e) {
+      console.error("Failed to pause directive:", e);
+    }
+  };
+
+  const handleContextArchive = async (directive: DirectiveSummary) => {
+    try {
+      await updateDirective(directive.id, { status: "archived" });
+      await refreshList();
+    } catch (e) {
+      console.error("Failed to archive directive:", e);
+    }
+  };
+
+  const handleContextDelete = async (directive: DirectiveSummary) => {
+    if (!window.confirm("Delete this directive?")) return;
+    try {
+      await remove(directive.id);
+      if (directive.id === selectedId) navigate("/directives");
+    } catch (e) {
+      console.error("Failed to delete:", e);
+    }
+  };
+
+  const handleContextGoToPR = (directive: DirectiveSummary) => {
+    if (directive.prUrl) window.open(directive.prUrl, "_blank");
+  };
+
   const handleCreate = async () => {
     if (!newTitle.trim() || !newGoal.trim()) return;
     try {
@@ -106,6 +147,11 @@ export default function DirectivesPage() {
             selectedId={selectedId ?? null}
             onSelect={(id) => navigate(`/directives/${id}`)}
             onCreate={() => setShowCreate(true)}
+            onStart={handleContextStart}
+            onPause={handleContextPause}
+            onArchive={handleContextArchive}
+            onDelete={handleContextDelete}
+            onGoToPR={handleContextGoToPR}
           />
         </div>
 
-- 
cgit v1.2.3

