From 55bf0714a20e651ab70b1eed01ec665cfefac6b4 Mon Sep 17 00:00:00 2001 From: soryu Date: Thu, 29 Jan 2026 17:22:59 +0000 Subject: Rename to command mode and update worktree to show committed changes --- makima/src/daemon/task/manager.rs | 90 +++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'makima/src/daemon/task/manager.rs') diff --git a/makima/src/daemon/task/manager.rs b/makima/src/daemon/task/manager.rs index dd133a2..1e04ca1 100644 --- a/makima/src/daemon/task/manager.rs +++ b/makima/src/daemon/task/manager.rs @@ -3329,7 +3329,7 @@ impl TaskManager { &self, task_id: Uuid, ) -> Result<(), DaemonError> { - // Get task's worktree path and branch + // Get task's worktree path, branch, and base_branch // If the task shares a supervisor's worktree, use the supervisor's worktree info let task_info = { let tasks = self.tasks.read().await; @@ -3340,12 +3340,14 @@ impl TaskManager { tasks.get(&supervisor_task_id).map(|supervisor| ( supervisor.worktree.as_ref().map(|w| w.path.clone()), supervisor.worktree.as_ref().map(|w| w.branch.clone()), + supervisor.base_branch.clone(), )) } else { // Use the task's own worktree Some(( task.worktree.as_ref().map(|w| w.path.clone()), task.worktree.as_ref().map(|w| w.branch.clone()), + task.base_branch.clone(), )) } } else { @@ -3353,10 +3355,10 @@ impl TaskManager { } }; - let (worktree_path, branch) = match task_info { - Some((Some(path), branch)) => (Some(path), branch), - Some((None, _)) => (None, None), - None => (None, None), + let (worktree_path, branch, base_branch) = match task_info { + Some((Some(path), branch, base_branch)) => (Some(path), branch, base_branch), + Some((None, _, _)) => (None, None, None), + None => (None, None, None), }; if worktree_path.is_none() { @@ -3419,7 +3421,7 @@ impl TaskManager { .output() .await; - let status_lines: Vec<(String, String)> = match status_output { + let uncommitted_status_lines: Vec<(String, String)> = match status_output { Ok(output) if output.status.success() => { String::from_utf8_lossy(&output.stdout) .lines() @@ -3436,14 +3438,78 @@ impl TaskManager { _ => vec![], }; - // Get numstat for line counts (staged + unstaged) - let numstat_output = tokio::process::Command::new("git") - .current_dir(&path) - .args(["diff", "HEAD", "--numstat"]) - .output() - .await; + // If there are uncommitted changes, use them. Otherwise, compare against base branch. + // Track effective_base_branch for reuse in numstat query + let (status_lines, effective_base_for_diff) = if !uncommitted_status_lines.is_empty() { + (uncommitted_status_lines, None) + } else { + // No uncommitted changes - try to get committed changes vs base branch + // First, try to detect the base branch if not provided + let effective_base_branch = if let Some(ref base) = base_branch { + Some(base.clone()) + } else { + // Auto-detect the default branch + self.worktree_manager.detect_default_branch(&path).await.ok() + }; + + if let Some(ref base) = effective_base_branch { + // Get committed changes using git diff --name-status + let diff_base = format!("origin/{}...HEAD", base); + let name_status_output = tokio::process::Command::new("git") + .current_dir(&path) + .args(["diff", "--name-status", &diff_base]) + .output() + .await; + + let committed_status_lines: Vec<(String, String)> = match name_status_output { + Ok(output) if output.status.success() => { + String::from_utf8_lossy(&output.stdout) + .lines() + .filter_map(|line| { + let parts: Vec<&str> = line.splitn(2, '\t').collect(); + if parts.len() >= 2 { + let status = parts[0].trim().to_string(); + let file_path = parts[1].to_string(); + Some((file_path, status)) + } else { + None + } + }) + .collect() + } + _ => vec![], + }; + if !committed_status_lines.is_empty() { + (committed_status_lines, Some(base.clone())) + } else { + (vec![], None) + } + } else { + (vec![], None) + } + }; + + // Get numstat for line counts + // If we have effective_base_for_diff, compare against origin/{base_branch} + // Otherwise compare against HEAD for uncommitted changes let mut file_stats: std::collections::HashMap = std::collections::HashMap::new(); + + let numstat_output = if let Some(ref base) = effective_base_for_diff { + let diff_base = format!("origin/{}...HEAD", base); + tokio::process::Command::new("git") + .current_dir(&path) + .args(["diff", "--numstat", &diff_base]) + .output() + .await + } else { + tokio::process::Command::new("git") + .current_dir(&path) + .args(["diff", "HEAD", "--numstat"]) + .output() + .await + }; + if let Ok(output) = numstat_output { if output.status.success() { for line in String::from_utf8_lossy(&output.stdout).lines() { -- cgit v1.2.3