summaryrefslogtreecommitdiff
path: root/makima/frontend/src
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-02-17 16:48:39 +0000
committerGitHub <noreply@github.com>2026-02-17 16:48:39 +0000
commitaee6cda5fc8c44ebc45b274d07a1ed64052e3699 (patch)
treeb484ced697dab34004ceeec826e1b884162f0f49 /makima/frontend/src
parent049fd3e8a15952627954678838ca5382c11ecd04 (diff)
downloadsoryu-aee6cda5fc8c44ebc45b274d07a1ed64052e3699.tar.gz
soryu-aee6cda5fc8c44ebc45b274d07a1ed64052e3699.zip
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)
Diffstat (limited to 'makima/frontend/src')
-rw-r--r--makima/frontend/src/components/directives/DirectiveDetail.tsx25
-rw-r--r--makima/frontend/src/hooks/useDirectives.ts8
-rw-r--r--makima/frontend/src/lib/api.ts6
-rw-r--r--makima/frontend/src/routes/directives.tsx4
4 files changed, 19 insertions, 24 deletions
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<void>;
}
@@ -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
</button>
+ <button
+ type="button"
+ onClick={onCleanup}
+ className="text-[10px] font-mono text-[#7788aa] hover:text-white border border-[#2a3a5a] rounded px-2 py-1"
+ >
+ Clean up
+ </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>
- )}
{completedSteps > 0 && !directive.completionTaskId && (
<button
type="button"
@@ -360,7 +355,7 @@ export function DirectiveDetail({
<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 ${hasTerminalTasks ? "" : "ml-auto"}`}
+ className="text-[10px] font-mono text-red-400 hover:text-red-300 border border-red-800 rounded px-2 py-1 ml-auto"
>
Delete
</button>
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<Dir
return res.json();
}
-export async function cleanupDirectiveTasks(id: string): Promise<{ deleted: number }> {
- 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}
/>