From e8b6669d929ad7ec0c6776a71c9b438e57f798a4 Mon Sep 17 00:00:00 2001 From: AndyMik90 Date: Tue, 16 Dec 2025 10:54:17 +0100 Subject: [PATCH] merge orcehestrator logic --- auto-claude-ui/electron.vite.config.ts | 6 + .../src/main/ipc-handlers/task-handlers.ts | 6 +- .../components/task-detail/TaskReview.tsx | 57 +- .../task-detail/hooks/useTaskDetail.ts | 3 +- auto-claude-ui/src/shared/types/task.ts | 17 + auto-claude/cli/workspace_commands.py | 188 ++- auto-claude/merge/__init__.py | 3 +- auto-claude/workspace.py | 1086 ++++++++++++++++- 8 files changed, 1337 insertions(+), 29 deletions(-) diff --git a/auto-claude-ui/electron.vite.config.ts b/auto-claude-ui/electron.vite.config.ts index 744d887c..152ed8b1 100644 --- a/auto-claude-ui/electron.vite.config.ts +++ b/auto-claude-ui/electron.vite.config.ts @@ -41,6 +41,12 @@ export default defineConfig({ '@': resolve(__dirname, 'src/renderer'), '@shared': resolve(__dirname, 'src/shared') } + }, + server: { + watch: { + // Ignore worktrees directory to prevent HMR conflicts during merge operations + ignored: ['**/.worktrees/**', '**/node_modules/**', '**/.git/**'] + } } } }); diff --git a/auto-claude-ui/src/main/ipc-handlers/task-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/task-handlers.ts index f83658b4..a86a278d 100644 --- a/auto-claude-ui/src/main/ipc-handlers/task-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/task-handlers.ts @@ -1810,8 +1810,10 @@ export function registerTaskHandlers( totalFiles: 0, conflictFiles: 0, totalConflicts: 0, - autoMergeable: 0 - } + autoMergeable: 0, + hasGitConflicts: false + }, + gitConflicts: result.gitConflicts || null } } }); diff --git a/auto-claude-ui/src/renderer/components/task-detail/TaskReview.tsx b/auto-claude-ui/src/renderer/components/task-detail/TaskReview.tsx index b76f3855..45d49ebd 100644 --- a/auto-claude-ui/src/renderer/components/task-detail/TaskReview.tsx +++ b/auto-claude-ui/src/renderer/components/task-detail/TaskReview.tsx @@ -29,7 +29,7 @@ import { } from '../ui/alert-dialog'; import { Badge } from '../ui/badge'; import { cn } from '../../lib/utils'; -import type { Task, WorktreeStatus, WorktreeDiff, MergeConflict, MergeStats } from '../../../shared/types'; +import type { Task, WorktreeStatus, WorktreeDiff, MergeConflict, MergeStats, GitConflictInfo } from '../../../shared/types'; interface TaskReviewProps { task: Task; @@ -46,7 +46,7 @@ interface TaskReviewProps { stageOnly: boolean; stagedSuccess: string | null; stagedProjectPath: string | undefined; - mergePreview: { files: string[]; conflicts: MergeConflict[]; summary: MergeStats } | null; + mergePreview: { files: string[]; conflicts: MergeConflict[]; summary: MergeStats; gitConflicts?: GitConflictInfo } | null; isLoadingPreview: boolean; showConflictDialog: boolean; onFeedbackChange: (value: string) => void; @@ -270,15 +270,22 @@ export function TaskReview({ {mergePreview && (
c.severity === 'high' || c.severity === 'critical') - ? "bg-destructive/10 border-destructive/30" - : "bg-warning/10 border-warning/30" + mergePreview.gitConflicts?.hasConflicts + ? "bg-warning/10 border-warning/30" // AI will resolve - show warning not error + : mergePreview.conflicts.length === 0 + ? "bg-success/10 border-success/30" + : mergePreview.conflicts.some(c => c.severity === 'high' || c.severity === 'critical') + ? "bg-destructive/10 border-destructive/30" + : "bg-warning/10 border-warning/30" )}>
- {mergePreview.conflicts.length === 0 ? ( + {mergePreview.gitConflicts?.hasConflicts ? ( + <> + + Branch Diverged - AI Will Resolve + + ) : mergePreview.conflicts.length === 0 ? ( <> No Conflicts Detected @@ -301,9 +308,29 @@ export function TaskReview({ )}
+ {/* Show git conflict details if present */} + {mergePreview.gitConflicts?.hasConflicts && ( +
+

Branch has diverged - AI will resolve

+

+ The main branch has {mergePreview.gitConflicts.commitsBehind} new commit{mergePreview.gitConflicts.commitsBehind !== 1 ? 's' : ''} since this worktree was created. + {mergePreview.gitConflicts.conflictingFiles.length} file{mergePreview.gitConflicts.conflictingFiles.length !== 1 ? 's' : ''} will need intelligent merging: +

+
    + {mergePreview.gitConflicts.conflictingFiles.map((file, idx) => ( +
  • {file}
  • + ))} +
+

+ AI will automatically merge these conflicts when you click Stage Changes. +

+
+ )}
Files to merge: {mergePreview.summary.totalFiles}
- {mergePreview.conflicts.length > 0 ? ( + {mergePreview.gitConflicts?.hasConflicts ? ( +
AI will resolve conflicts
+ ) : mergePreview.conflicts.length > 0 ? ( <>
Auto-mergeable: {mergePreview.summary.autoMergeable}
{mergePreview.summary.aiResolved !== undefined && ( @@ -334,15 +361,23 @@ export function TaskReview({ {/* Primary Actions */}