From aee6cda5fc8c44ebc45b274d07a1ed64052e3699 Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 17 Feb 2026 16:48:39 +0000 Subject: feat: smart cleanup, order linking, and improved PR titles (#69) * feat: soryu-co/soryu: Reorder navigation: move Orders before Contracts * feat: soryu-co/soryu: Generate PR titles from step content instead of directive title * feat: soryu-co/soryu: Add orderId field to step creation and link orders to steps * feat: soryu-co/soryu: Handle completed orders during plan-orders flow * WIP: heartbeat checkpoint * Merge origin/makima/soryu-co-soryu--handle-completed-orders-during-pla-5aa9a15b (resolved conflicts) --- .../src/components/directives/DirectiveDetail.tsx | 25 +++++++++------------- makima/frontend/src/hooks/useDirectives.ts | 8 +++---- makima/frontend/src/lib/api.ts | 6 +++--- makima/frontend/src/routes/directives.tsx | 4 ++-- 4 files changed, 19 insertions(+), 24 deletions(-) (limited to 'makima/frontend/src') diff --git a/makima/frontend/src/components/directives/DirectiveDetail.tsx b/makima/frontend/src/components/directives/DirectiveDetail.tsx index c9dac37..98940d0 100644 --- a/makima/frontend/src/components/directives/DirectiveDetail.tsx +++ b/makima/frontend/src/components/directives/DirectiveDetail.tsx @@ -25,7 +25,7 @@ interface DirectiveDetailProps { onUpdate: (req: UpdateDirectiveRequest) => void; onDelete: () => void; onRefresh: () => void; - onCleanupTasks: () => void; + onCleanup: () => void; onPickUpOrders: () => Promise<{ message: string; orderCount: number; taskId: string | null } | null>; onCreatePR: () => Promise; } @@ -42,7 +42,7 @@ export function DirectiveDetail({ onUpdate, onDelete, onRefresh, - onCleanupTasks, + onCleanup, onPickUpOrders, onCreatePR, }: DirectiveDetailProps) { @@ -66,9 +66,6 @@ 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)); - // Get pending questions for this directive's tasks const { pendingQuestions, submitAnswer } = useSupervisorQuestions(); const directiveTaskIds = useMemo(() => { @@ -325,17 +322,15 @@ export function DirectiveDetail({ > Update Goal + )} - {hasTerminalTasks && ( - - )} {completedSteps > 0 && !directive.completionTaskId && ( diff --git a/makima/frontend/src/hooks/useDirectives.ts b/makima/frontend/src/hooks/useDirectives.ts index 18544da..898f671 100644 --- a/makima/frontend/src/hooks/useDirectives.ts +++ b/makima/frontend/src/hooks/useDirectives.ts @@ -19,7 +19,7 @@ import { failDirectiveStep, skipDirectiveStep, updateDirectiveGoal, - cleanupDirectiveTasks, + cleanupDirective, pickUpOrders as pickUpOrdersApi, createDirectivePR, } from "../lib/api"; @@ -173,9 +173,9 @@ export function useDirective(id: string | undefined) { await refresh(); }, [id, refresh]); - const cleanupTasks = useCallback(async () => { + const cleanup = useCallback(async () => { if (!id) return; - await cleanupDirectiveTasks(id); + await cleanupDirective(id); await refresh(); }, [id, refresh]); @@ -197,7 +197,7 @@ export function useDirective(id: string | undefined) { update, addStep, removeStep, start, pause, advance, completeStep, failStep, skipStep, - updateGoal, cleanupTasks, + updateGoal, cleanup, pickUpOrders: pickUpOrdersFn, createPR, }; diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index ed628f7..43eaa05 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -3248,11 +3248,11 @@ export async function updateDirectiveGoal(id: string, goal: string): Promise { - const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/cleanup-tasks`, { +export async function cleanupDirective(id: string): Promise<{ message: string; taskId: string | null }> { + const res = await authFetch(`${API_BASE}/api/v1/directives/${id}/cleanup`, { method: "POST", }); - if (!res.ok) throw new Error(`Failed to cleanup tasks: ${res.statusText}`); + if (!res.ok) throw new Error(`Failed to cleanup directive: ${res.statusText}`); return res.json(); } diff --git a/makima/frontend/src/routes/directives.tsx b/makima/frontend/src/routes/directives.tsx index 2bb673c..cee4920 100644 --- a/makima/frontend/src/routes/directives.tsx +++ b/makima/frontend/src/routes/directives.tsx @@ -12,7 +12,7 @@ export default function DirectivesPage() { const navigate = useNavigate(); const { id: selectedId } = useParams<{ id: string }>(); const { directives, loading: listLoading, create, remove } = useDirectives(); - const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanupTasks, pickUpOrders, createPR } = useDirective(selectedId); + const { directive, refresh: refreshDetail, update, start, pause, advance, completeStep, failStep, skipStep, updateGoal, cleanup, pickUpOrders, createPR } = useDirective(selectedId); const [showCreate, setShowCreate] = useState(false); const [newTitle, setNewTitle] = useState(""); @@ -210,7 +210,7 @@ export default function DirectivesPage() { onUpdate={update} onDelete={handleDelete} onRefresh={refreshDetail} - onCleanupTasks={cleanupTasks} + onCleanup={cleanup} onPickUpOrders={pickUpOrders} onCreatePR={createPR} /> -- cgit v1.2.3