mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-03-20 23:13:07 +00:00
feat: Add GPT-5 model variants and improve Codex execution logic. Addressed code review comments
This commit is contained in:
@@ -27,6 +27,7 @@ import { getElectronAPI } from '@/lib/electron';
|
||||
import { toast } from 'sonner';
|
||||
import { useAppStore } from '@/store/app-store';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TruncatedFilePath } from '@/components/ui/truncated-file-path';
|
||||
import type { FileStatus } from '@/types/electron';
|
||||
|
||||
interface WorktreeInfo {
|
||||
@@ -566,9 +567,10 @@ export function CommitWorktreeDialog({
|
||||
<ChevronRight className="w-3 h-3 text-muted-foreground flex-shrink-0" />
|
||||
)}
|
||||
{getFileIcon(file.status)}
|
||||
<span className="text-xs font-mono truncate flex-1 text-foreground">
|
||||
{file.path}
|
||||
</span>
|
||||
<TruncatedFilePath
|
||||
path={file.path}
|
||||
className="text-xs font-mono flex-1 text-foreground"
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
'text-[10px] px-1.5 py-0.5 rounded border font-medium flex-shrink-0',
|
||||
|
||||
@@ -26,6 +26,7 @@ import { getElectronAPI } from '@/lib/electron';
|
||||
import { getHttpApiClient } from '@/lib/http-api-client';
|
||||
import { toast } from 'sonner';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TruncatedFilePath } from '@/components/ui/truncated-file-path';
|
||||
import type { FileStatus } from '@/types/electron';
|
||||
|
||||
interface WorktreeInfo {
|
||||
@@ -313,9 +314,12 @@ export function DiscardWorktreeChangesDialog({
|
||||
const result = await api.git.getDiffs(worktree.path);
|
||||
if (result.success) {
|
||||
const fileList = result.files ?? [];
|
||||
if (!cancelled) setError(null);
|
||||
if (!cancelled) setFiles(fileList);
|
||||
if (!cancelled) setDiffContent(result.diff ?? '');
|
||||
if (!cancelled) setSelectedFiles(new Set());
|
||||
} else {
|
||||
if (!cancelled) setError(result.error || 'Failed to fetch diffs');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -495,9 +499,10 @@ export function DiscardWorktreeChangesDialog({
|
||||
<ChevronRight className="w-3 h-3 text-muted-foreground flex-shrink-0" />
|
||||
)}
|
||||
{getFileIcon(file.status)}
|
||||
<span className="text-xs font-mono truncate flex-1 text-foreground">
|
||||
{file.path}
|
||||
</span>
|
||||
<TruncatedFilePath
|
||||
path={file.path}
|
||||
className="text-xs font-mono flex-1 text-foreground"
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
'text-[10px] px-1.5 py-0.5 rounded border font-medium flex-shrink-0',
|
||||
|
||||
@@ -42,6 +42,7 @@ type PullPhase =
|
||||
|
||||
interface PullResult {
|
||||
branch: string;
|
||||
remote?: string;
|
||||
pulled: boolean;
|
||||
message: string;
|
||||
hasLocalChanges?: boolean;
|
||||
@@ -115,6 +116,11 @@ export function GitPullDialog({
|
||||
setPullResult(result.result);
|
||||
setPhase('success');
|
||||
onPulled?.();
|
||||
} else {
|
||||
// Unexpected response: success but no recognizable fields
|
||||
setPullResult(result.result ?? null);
|
||||
setErrorMessage('Unexpected pull response');
|
||||
setPhase('error');
|
||||
}
|
||||
} catch (err) {
|
||||
setErrorMessage(err instanceof Error ? err.message : 'Failed to check for changes');
|
||||
@@ -160,8 +166,9 @@ export function GitPullDialog({
|
||||
const handleResolveWithAI = useCallback(() => {
|
||||
if (!worktree || !pullResult || !onCreateConflictResolutionFeature) return;
|
||||
|
||||
const effectiveRemote = pullResult.remote || remote;
|
||||
const conflictInfo: MergeConflictInfo = {
|
||||
sourceBranch: `${remote || 'origin'}/${pullResult.branch}`,
|
||||
sourceBranch: effectiveRemote ? `${effectiveRemote}/${pullResult.branch}` : pullResult.branch,
|
||||
targetBranch: pullResult.branch,
|
||||
targetWorktreePath: worktree.path,
|
||||
conflictFiles: pullResult.conflictFiles || [],
|
||||
|
||||
@@ -25,6 +25,7 @@ import { Spinner } from '@/components/ui/spinner';
|
||||
import { getHttpApiClient } from '@/lib/http-api-client';
|
||||
import { toast } from 'sonner';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TruncatedFilePath } from '@/components/ui/truncated-file-path';
|
||||
import type { FileStatus } from '@/types/electron';
|
||||
|
||||
interface WorktreeInfo {
|
||||
@@ -514,9 +515,10 @@ export function StashChangesDialog({
|
||||
<ChevronRight className="w-3 h-3 text-muted-foreground flex-shrink-0" />
|
||||
)}
|
||||
{getFileIcon(file.status)}
|
||||
<span className="text-xs font-mono truncate flex-1 text-foreground">
|
||||
{file.path}
|
||||
</span>
|
||||
<TruncatedFilePath
|
||||
path={file.path}
|
||||
className="text-xs font-mono flex-1 text-foreground"
|
||||
/>
|
||||
<span
|
||||
className={cn(
|
||||
'text-[10px] px-1.5 py-0.5 rounded border font-medium flex-shrink-0',
|
||||
|
||||
@@ -930,6 +930,7 @@ export function useBoardActions({
|
||||
// - If the feature had a branch assigned, keep it (preserves worktree context)
|
||||
// - If no branch was assigned, it will show on the primary worktree
|
||||
const featureBranch = feature.branchName;
|
||||
const branchLabel = featureBranch ?? 'primary worktree';
|
||||
|
||||
// Check if the feature will be visible on the current worktree view
|
||||
const willBeVisibleOnCurrentView = !featureBranch
|
||||
@@ -949,7 +950,7 @@ export function useBoardActions({
|
||||
});
|
||||
} else {
|
||||
toast.success('Feature restored', {
|
||||
description: `Moved back to verified on branch "${featureBranch}": ${truncateDescription(feature.description)}`,
|
||||
description: `Moved back to verified on branch "${branchLabel}": ${truncateDescription(feature.description)}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -197,11 +197,23 @@ export function WorktreeActionsDropdown({
|
||||
|
||||
// Check git operations availability
|
||||
const canPerformGitOps = gitRepoStatus.isGitRepo && gitRepoStatus.hasCommits;
|
||||
const gitOpsDisabledReason = !gitRepoStatus.isGitRepo
|
||||
? 'Not a git repository'
|
||||
: !gitRepoStatus.hasCommits
|
||||
? 'Repository has no commits yet'
|
||||
: null;
|
||||
// While git status is loading, treat git ops as unavailable to avoid stale state enabling actions
|
||||
const isGitOpsAvailable = !isLoadingGitStatus && canPerformGitOps;
|
||||
const gitOpsDisabledReason = isLoadingGitStatus
|
||||
? 'Checking git status...'
|
||||
: !gitRepoStatus.isGitRepo
|
||||
? 'Not a git repository'
|
||||
: !gitRepoStatus.hasCommits
|
||||
? 'Repository has no commits yet'
|
||||
: null;
|
||||
|
||||
// Determine if the changes/PR section has any visible items
|
||||
const showCreatePR = (!worktree.isMain || worktree.hasChanges) && !hasPR;
|
||||
const showPRInfo = hasPR && !!worktree.pr;
|
||||
const hasChangesSectionContent = worktree.hasChanges || showCreatePR || showPRInfo;
|
||||
|
||||
// Determine if the destructive/bottom section has any visible items
|
||||
const hasDestructiveSectionContent = worktree.hasChanges || !worktree.isMain;
|
||||
|
||||
return (
|
||||
<DropdownMenu onOpenChange={onOpenChange}>
|
||||
@@ -232,7 +244,7 @@ export function WorktreeActionsDropdown({
|
||||
</>
|
||||
)}
|
||||
{/* Warning label when git operations are not available (only show once loaded) */}
|
||||
{!isLoadingGitStatus && !canPerformGitOps && (
|
||||
{!isLoadingGitStatus && !isGitOpsAvailable && (
|
||||
<>
|
||||
<DropdownMenuLabel className="text-xs flex items-center gap-2 text-amber-600 dark:text-amber-400">
|
||||
<AlertCircle className="w-3.5 h-3.5" />
|
||||
@@ -362,14 +374,16 @@ export function WorktreeActionsDropdown({
|
||||
)}
|
||||
<TooltipWrapper showTooltip={!!gitOpsDisabledReason} tooltipContent={gitOpsDisabledReason}>
|
||||
<DropdownMenuItem
|
||||
onClick={() => canPerformGitOps && onPull(worktree)}
|
||||
disabled={isPulling || !canPerformGitOps}
|
||||
className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
|
||||
onClick={() => isGitOpsAvailable && onPull(worktree)}
|
||||
disabled={isPulling || !isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<Download className={cn('w-3.5 h-3.5 mr-2', isPulling && 'animate-pulse')} />
|
||||
{isPulling ? 'Pulling...' : 'Pull'}
|
||||
{!canPerformGitOps && <AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />}
|
||||
{canPerformGitOps && behindCount > 0 && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
{isGitOpsAvailable && behindCount > 0 && (
|
||||
<span className="ml-auto text-[10px] bg-muted px-1.5 py-0.5 rounded">
|
||||
{behindCount} behind
|
||||
</span>
|
||||
@@ -379,26 +393,28 @@ export function WorktreeActionsDropdown({
|
||||
<TooltipWrapper showTooltip={!!gitOpsDisabledReason} tooltipContent={gitOpsDisabledReason}>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!canPerformGitOps) return;
|
||||
if (!isGitOpsAvailable) return;
|
||||
if (!hasRemoteBranch) {
|
||||
onPushNewBranch(worktree);
|
||||
} else {
|
||||
onPush(worktree);
|
||||
}
|
||||
}}
|
||||
disabled={isPushing || (hasRemoteBranch && aheadCount === 0) || !canPerformGitOps}
|
||||
className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
|
||||
disabled={isPushing || (hasRemoteBranch && aheadCount === 0) || !isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<Upload className={cn('w-3.5 h-3.5 mr-2', isPushing && 'animate-pulse')} />
|
||||
{isPushing ? 'Pushing...' : 'Push'}
|
||||
{!canPerformGitOps && <AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />}
|
||||
{canPerformGitOps && !hasRemoteBranch && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
{isGitOpsAvailable && !hasRemoteBranch && (
|
||||
<span className="ml-auto inline-flex items-center gap-0.5 text-[10px] bg-amber-500/20 text-amber-600 dark:text-amber-400 px-1.5 py-0.5 rounded">
|
||||
<CloudOff className="w-2.5 h-2.5" />
|
||||
local only
|
||||
</span>
|
||||
)}
|
||||
{canPerformGitOps && hasRemoteBranch && aheadCount > 0 && (
|
||||
{isGitOpsAvailable && hasRemoteBranch && aheadCount > 0 && (
|
||||
<span className="ml-auto text-[10px] bg-primary/20 text-primary px-1.5 py-0.5 rounded">
|
||||
{aheadCount} ahead
|
||||
</span>
|
||||
@@ -407,27 +423,31 @@ export function WorktreeActionsDropdown({
|
||||
</TooltipWrapper>
|
||||
<TooltipWrapper showTooltip={!!gitOpsDisabledReason} tooltipContent={gitOpsDisabledReason}>
|
||||
<DropdownMenuItem
|
||||
onClick={() => canPerformGitOps && onResolveConflicts(worktree)}
|
||||
disabled={!canPerformGitOps}
|
||||
onClick={() => isGitOpsAvailable && onResolveConflicts(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn(
|
||||
'text-xs text-purple-500 focus:text-purple-600',
|
||||
!canPerformGitOps && 'opacity-50 cursor-not-allowed'
|
||||
!isGitOpsAvailable && 'opacity-50 cursor-not-allowed'
|
||||
)}
|
||||
>
|
||||
<GitMerge className="w-3.5 h-3.5 mr-2" />
|
||||
Merge & Rebase
|
||||
{!canPerformGitOps && <AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />}
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
</TooltipWrapper>
|
||||
<TooltipWrapper showTooltip={!!gitOpsDisabledReason} tooltipContent={gitOpsDisabledReason}>
|
||||
<DropdownMenuItem
|
||||
onClick={() => canPerformGitOps && onViewCommits(worktree)}
|
||||
disabled={!canPerformGitOps}
|
||||
className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
|
||||
onClick={() => isGitOpsAvailable && onViewCommits(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<History className="w-3.5 h-3.5 mr-2" />
|
||||
View Commits
|
||||
{!canPerformGitOps && <AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />}
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
</TooltipWrapper>
|
||||
{/* Cherry-pick commits from another branch */}
|
||||
@@ -437,13 +457,13 @@ export function WorktreeActionsDropdown({
|
||||
tooltipContent={gitOpsDisabledReason}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => canPerformGitOps && onCherryPick(worktree)}
|
||||
disabled={!canPerformGitOps}
|
||||
className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
|
||||
onClick={() => isGitOpsAvailable && onCherryPick(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<Cherry className="w-3.5 h-3.5 mr-2" />
|
||||
Cherry Pick
|
||||
{!canPerformGitOps && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
@@ -451,7 +471,7 @@ export function WorktreeActionsDropdown({
|
||||
)}
|
||||
{/* Stash operations - combined submenu or simple item */}
|
||||
{(onStashChanges || onViewStashes) && (
|
||||
<TooltipWrapper showTooltip={!canPerformGitOps} tooltipContent={gitOpsDisabledReason}>
|
||||
<TooltipWrapper showTooltip={!isGitOpsAvailable} tooltipContent={gitOpsDisabledReason}>
|
||||
{onViewStashes && worktree.hasChanges && onStashChanges ? (
|
||||
// Both "Stash Changes" (primary) and "View Stashes" (secondary) are available - show split submenu
|
||||
<DropdownMenuSub>
|
||||
@@ -459,18 +479,18 @@ export function WorktreeActionsDropdown({
|
||||
{/* Main clickable area - stash changes (primary action) */}
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!canPerformGitOps) return;
|
||||
if (!isGitOpsAvailable) return;
|
||||
onStashChanges(worktree);
|
||||
}}
|
||||
disabled={!canPerformGitOps}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn(
|
||||
'text-xs flex-1 pr-0 rounded-r-none',
|
||||
!canPerformGitOps && 'opacity-50 cursor-not-allowed'
|
||||
!isGitOpsAvailable && 'opacity-50 cursor-not-allowed'
|
||||
)}
|
||||
>
|
||||
<Archive className="w-3.5 h-3.5 mr-2" />
|
||||
Stash Changes
|
||||
{!canPerformGitOps && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
@@ -478,9 +498,9 @@ export function WorktreeActionsDropdown({
|
||||
<DropdownMenuSubTrigger
|
||||
className={cn(
|
||||
'text-xs px-1 rounded-l-none border-l border-border/30 h-8',
|
||||
!canPerformGitOps && 'opacity-50 cursor-not-allowed'
|
||||
!isGitOpsAvailable && 'opacity-50 cursor-not-allowed'
|
||||
)}
|
||||
disabled={!canPerformGitOps}
|
||||
disabled={!isGitOpsAvailable}
|
||||
/>
|
||||
</div>
|
||||
<DropdownMenuSubContent>
|
||||
@@ -494,19 +514,19 @@ export function WorktreeActionsDropdown({
|
||||
// Only one action is meaningful - render a simple menu item without submenu
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
if (!canPerformGitOps) return;
|
||||
if (!isGitOpsAvailable) return;
|
||||
if (worktree.hasChanges && onStashChanges) {
|
||||
onStashChanges(worktree);
|
||||
} else if (onViewStashes) {
|
||||
onViewStashes(worktree);
|
||||
}
|
||||
}}
|
||||
disabled={!canPerformGitOps}
|
||||
className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<Archive className="w-3.5 h-3.5 mr-2" />
|
||||
{worktree.hasChanges && onStashChanges ? 'Stash Changes' : 'Stashes'}
|
||||
{!canPerformGitOps && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
@@ -639,7 +659,7 @@ export function WorktreeActionsDropdown({
|
||||
Re-run Init Script
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
{(hasChangesSectionContent || hasDestructiveSectionContent) && <DropdownMenuSeparator />}
|
||||
|
||||
{worktree.hasChanges && (
|
||||
<DropdownMenuItem onClick={() => onViewChanges(worktree)} className="text-xs">
|
||||
@@ -649,43 +669,43 @@ export function WorktreeActionsDropdown({
|
||||
)}
|
||||
{worktree.hasChanges && (
|
||||
<TooltipWrapper
|
||||
showTooltip={!gitRepoStatus.isGitRepo}
|
||||
tooltipContent="Not a git repository"
|
||||
showTooltip={!!gitOpsDisabledReason}
|
||||
tooltipContent={gitOpsDisabledReason}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => gitRepoStatus.isGitRepo && onCommit(worktree)}
|
||||
disabled={!gitRepoStatus.isGitRepo}
|
||||
className={cn('text-xs', !gitRepoStatus.isGitRepo && 'opacity-50 cursor-not-allowed')}
|
||||
onClick={() => isGitOpsAvailable && onCommit(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<GitCommit className="w-3.5 h-3.5 mr-2" />
|
||||
Commit Changes
|
||||
{!gitRepoStatus.isGitRepo && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
</TooltipWrapper>
|
||||
)}
|
||||
{/* Show PR option for non-primary worktrees, or primary worktree with changes */}
|
||||
{(!worktree.isMain || worktree.hasChanges) && !hasPR && (
|
||||
{showCreatePR && (
|
||||
<TooltipWrapper
|
||||
showTooltip={!!gitOpsDisabledReason}
|
||||
tooltipContent={gitOpsDisabledReason}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => canPerformGitOps && onCreatePR(worktree)}
|
||||
disabled={!canPerformGitOps}
|
||||
className={cn('text-xs', !canPerformGitOps && 'opacity-50 cursor-not-allowed')}
|
||||
onClick={() => isGitOpsAvailable && onCreatePR(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn('text-xs', !isGitOpsAvailable && 'opacity-50 cursor-not-allowed')}
|
||||
>
|
||||
<GitPullRequest className="w-3.5 h-3.5 mr-2" />
|
||||
Create Pull Request
|
||||
{!canPerformGitOps && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
</TooltipWrapper>
|
||||
)}
|
||||
{/* Show PR info and Address Comments button if PR exists */}
|
||||
{hasPR && worktree.pr && (
|
||||
{showPRInfo && worktree.pr && (
|
||||
<>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
@@ -722,23 +742,23 @@ export function WorktreeActionsDropdown({
|
||||
</DropdownMenuItem>
|
||||
</>
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
{hasChangesSectionContent && hasDestructiveSectionContent && <DropdownMenuSeparator />}
|
||||
{worktree.hasChanges && (
|
||||
<TooltipWrapper
|
||||
showTooltip={!gitRepoStatus.isGitRepo}
|
||||
tooltipContent="Not a git repository"
|
||||
showTooltip={!!gitOpsDisabledReason}
|
||||
tooltipContent={gitOpsDisabledReason}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => gitRepoStatus.isGitRepo && onDiscardChanges(worktree)}
|
||||
disabled={!gitRepoStatus.isGitRepo}
|
||||
onClick={() => isGitOpsAvailable && onDiscardChanges(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn(
|
||||
'text-xs text-destructive focus:text-destructive',
|
||||
!gitRepoStatus.isGitRepo && 'opacity-50 cursor-not-allowed'
|
||||
!isGitOpsAvailable && 'opacity-50 cursor-not-allowed'
|
||||
)}
|
||||
>
|
||||
<Undo2 className="w-3.5 h-3.5 mr-2" />
|
||||
Discard Changes
|
||||
{!gitRepoStatus.isGitRepo && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
@@ -751,16 +771,16 @@ export function WorktreeActionsDropdown({
|
||||
tooltipContent={gitOpsDisabledReason}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => canPerformGitOps && onMerge(worktree)}
|
||||
disabled={!canPerformGitOps}
|
||||
onClick={() => isGitOpsAvailable && onMerge(worktree)}
|
||||
disabled={!isGitOpsAvailable}
|
||||
className={cn(
|
||||
'text-xs text-green-600 focus:text-green-700',
|
||||
!canPerformGitOps && 'opacity-50 cursor-not-allowed'
|
||||
!isGitOpsAvailable && 'opacity-50 cursor-not-allowed'
|
||||
)}
|
||||
>
|
||||
<GitMerge className="w-3.5 h-3.5 mr-2" />
|
||||
Merge Branch
|
||||
{!canPerformGitOps && (
|
||||
{!isGitOpsAvailable && (
|
||||
<AlertCircle className="w-3 h-3 ml-auto text-muted-foreground" />
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
|
||||
@@ -633,14 +633,14 @@ export function WorktreePanel({
|
||||
setPullDialogRemote(remote);
|
||||
setPullDialogWorktree(worktree);
|
||||
setPullDialogOpen(true);
|
||||
await handlePull(worktree, remote);
|
||||
await _handlePull(worktree, remote);
|
||||
} else {
|
||||
await handlePush(worktree, remote);
|
||||
}
|
||||
fetchBranches(worktree.path);
|
||||
fetchWorktrees();
|
||||
},
|
||||
[selectRemoteOperation, handlePush, fetchBranches, fetchWorktrees]
|
||||
[selectRemoteOperation, _handlePull, handlePush, fetchBranches, fetchWorktrees]
|
||||
);
|
||||
|
||||
// Handle confirming the push to remote dialog
|
||||
|
||||
Reference in New Issue
Block a user