From 265f8cf14fec9d7116d09af49e4b48b357faceda Mon Sep 17 00:00:00 2001 From: soryu Date: Thu, 22 Jan 2026 13:17:17 +0000 Subject: Fix completion actions: default to PR and support remote repos (#21) * Fix completion actions: default to PR and support remote repos - Change default completion action from 'branch' to 'pr' for tasks using daemon working directory - Allow PR completion action to work without target_repo_path if the worktree already has an origin remote configured (e.g., when cloned from a remote URL) - Update create_pull_request to accept optional target_repo parameter Co-Authored-By: Claude Opus 4.5 * Add dismiss functionality for completed standalone tasks ## Changes ### Backend - Add 'hidden' field to Task model (models.rs) - Add database migration for hidden column (20250122000000_add_task_hidden.sql) - Update task listing queries to include hidden field and filter out hidden tasks - Update update_task_for_owner to handle hidden field ### Frontend - Add hidden field to TaskSummary interface (api.ts) - Add dismissTask API function (api.ts) - Add hideTask function to useTasks hook - Add Dismiss button to TaskList for completed standalone tasks - Wire up onDismiss handler in mesh.tsx route ## Behavior - Completed standalone tasks (tasks without a contract) show a "Dismiss" button - Dismissing a task sets hidden=true and removes it from the task list - Hidden tasks are filtered out by default in all task listing queries Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- makima/frontend/src/components/mesh/TaskList.tsx | 38 +++++++++++++++++------- makima/frontend/src/hooks/useTasks.ts | 17 +++++++++++ makima/frontend/src/lib/api.ts | 16 ++++++++++ makima/frontend/src/routes/mesh.tsx | 10 ++++++- 4 files changed, 69 insertions(+), 12 deletions(-) (limited to 'makima/frontend') diff --git a/makima/frontend/src/components/mesh/TaskList.tsx b/makima/frontend/src/components/mesh/TaskList.tsx index e3f2862..016fef5 100644 --- a/makima/frontend/src/components/mesh/TaskList.tsx +++ b/makima/frontend/src/components/mesh/TaskList.tsx @@ -6,6 +6,7 @@ interface TaskListProps { loading: boolean; onSelect: (id: string) => void; onDelete: (id: string) => void; + onDismiss: (id: string) => void; onCreate: () => void; } @@ -88,6 +89,7 @@ export function TaskList({ loading, onSelect, onDelete, + onDismiss, onCreate, }: TaskListProps) { // Filter state - default to 'active' to show only active contracts @@ -300,17 +302,31 @@ export function TaskList({ {/* Supervisor tasks cannot be deleted directly - they are deleted with the contract */} - {!task.isSupervisor && ( - - )} +
+ {/* Show dismiss button for completed standalone tasks (tasks without a contract) */} + {!task.contractId && (task.status === "done" || task.status === "failed" || task.status === "merged") && ( + + )} + {!task.isSupervisor && ( + + )} +
))} diff --git a/makima/frontend/src/hooks/useTasks.ts b/makima/frontend/src/hooks/useTasks.ts index 6e6c992..4667c4c 100644 --- a/makima/frontend/src/hooks/useTasks.ts +++ b/makima/frontend/src/hooks/useTasks.ts @@ -5,6 +5,7 @@ import { createTask, updateTask, deleteTask, + dismissTask, VersionConflictError, type TaskSummary, type TaskWithSubtasks, @@ -110,6 +111,21 @@ export function useTasks() { [fetchTasks] ); + const hideTask = useCallback( + async (id: string): Promise => { + setError(null); + try { + await dismissTask(id); + await fetchTasks(); // Refresh list + return true; + } catch (e) { + setError(e instanceof Error ? e.message : "Failed to dismiss task"); + return false; + } + }, + [fetchTasks] + ); + // Initial fetch useEffect(() => { fetchTasks(); @@ -126,5 +142,6 @@ export function useTasks() { saveTask, editTask, removeTask, + hideTask, }; } diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts index aeaa218..76ee4d4 100644 --- a/makima/frontend/src/lib/api.ts +++ b/makima/frontend/src/lib/api.ts @@ -543,6 +543,8 @@ export interface TaskSummary { subtaskCount: number; /** Whether this is a supervisor task (contract orchestrator) */ isSupervisor: boolean; + /** Whether this task is hidden from the UI (user dismissed it) */ + hidden: boolean; version: number; createdAt: string; updatedAt: string; @@ -639,6 +641,8 @@ export interface UpdateTaskRequest { targetRepoPath?: string; /** Action on completion: "none", "branch", "merge", "pr" */ completionAction?: CompletionAction; + /** Whether this task is hidden from the UI (user dismissed it) */ + hidden?: boolean; version?: number; } @@ -2657,3 +2661,15 @@ export function getSupervisorStatus( canResume, }; } + +// ============================================================================= +// Task Dismiss (Hide) Functions +// ============================================================================= + +/** + * Dismiss (hide) a completed standalone task from the UI. + * This marks the task as hidden so it won't appear in the task list. + */ +export async function dismissTask(taskId: string): Promise { + return updateTask(taskId, { hidden: true }); +} diff --git a/makima/frontend/src/routes/mesh.tsx b/makima/frontend/src/routes/mesh.tsx index 425721d..fb366a2 100644 --- a/makima/frontend/src/routes/mesh.tsx +++ b/makima/frontend/src/routes/mesh.tsx @@ -81,7 +81,7 @@ export default function MeshPage() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const { isAuthenticated, isAuthConfigured, isLoading: authLoading } = useAuth(); - const { tasks, loading, error, conflict, clearConflict, fetchTask, fetchTasks, editTask, removeTask, saveTask } = useTasks(); + const { tasks, loading, error, conflict, clearConflict, fetchTask, fetchTasks, editTask, removeTask, hideTask, saveTask } = useTasks(); const { pendingQuestions, submitAnswer } = useSupervisorQuestions(); // Memoize pending question IDs for efficient lookup @@ -408,6 +408,13 @@ export default function MeshPage() { [removeTask, id, taskDetail, navigate] ); + const handleDismiss = useCallback( + async (taskId: string) => { + await hideTask(taskId); + }, + [hideTask] + ); + const handleStart = useCallback( async (taskId: string) => { try { @@ -868,6 +875,7 @@ export default function MeshPage() { loading={loading || creating} onSelect={handleSelectTask} onDelete={handleDelete} + onDismiss={handleDismiss} onCreate={handleCreate} /> -- cgit v1.2.3