From 1f91de5cbcbba9696a0a71fa1e28f433dad5ff4e Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sat, 24 Jan 2026 22:12:07 +0700 Subject: [PATCH] Update files --- packages/app/src/components/git-diff-pane.tsx | 222 ++++++++++-------- packages/server/src/utils/checkout-git.ts | 6 +- scripts/dev.sh | 6 +- 3 files changed, 127 insertions(+), 107 deletions(-) diff --git a/packages/app/src/components/git-diff-pane.tsx b/packages/app/src/components/git-diff-pane.tsx index 4c3fad20e..b9f9b5beb 100644 --- a/packages/app/src/components/git-diff-pane.tsx +++ b/packages/app/src/components/git-diff-pane.tsx @@ -14,7 +14,7 @@ import { ScrollView, type ScrollView as ScrollViewType } from "react-native-gest import { StyleSheet, useUnistyles } from "react-native-unistyles"; import AsyncStorage from "@react-native-async-storage/async-storage"; import * as Linking from "expo-linking"; -import { ChevronDown, ChevronRight, GitBranch, MoreVertical, RotateCcw } from "lucide-react-native"; +import { ChevronDown, ChevronRight, GitBranch, MoreVertical } from "lucide-react-native"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useSessionStore } from "@/stores/session-store"; import { @@ -32,7 +32,6 @@ import { getNowMs, isPerfLoggingEnabled, perfLog } from "@/utils/perf"; import { DropdownMenu, DropdownMenuContent, - DropdownMenuHint, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, @@ -121,6 +120,7 @@ function HighlightedText({ tokens, lineType }: HighlightedTextProps) { ); } + interface DiffFileSectionProps { file: ParsedDiffFile; isExpanded: boolean; @@ -824,67 +824,12 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) { {branchLabel} - {isStatusFetching && ( - - )} + {isStatusFetching && ( + + )} {isGit ? ( - - - - {diffMode === "uncommitted" ? "Working" : "Base"} - - - - - setDiffMode("uncommitted")} - > - Working - - setDiffMode("base")} - > - Base - - - - ) : null} - - - {isGit ? ( - - - {canShowCommit ? ( - commitMutation.mutate()} - disabled={commitDisabled} - > - {commitMutation.isPending ? ( - - ) : ( - Commit… - )} - - ) : ( - - )} - - + {canShowShip ? ( ) : ( - <> - - {resolvedShipPrimary === "merge" ? "Merge" : prActionLabel} - - - into {baseRefLabel} - - + + {resolvedShipPrimary === "merge" ? "Merge branch" : prActionLabel} + )} @@ -940,19 +880,15 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) { { void persistShipDefault("merge"); mergeMutation.mutate(); }} > - Merge into {baseRefLabel} + Merge branch - {mergeDisabled && hasUncommittedChanges ? ( - Requires a clean working tree. - ) : null} - - - {hasPullRequest ? "Open PR" : `Create PR into ${baseRefLabel}`} + {hasPullRequest ? "Open PR" : "Create PR"} @@ -982,35 +918,56 @@ export function GitDiffPane({ serverId, agentId }: GitDiffPaneProps) { - } - onSelect={handleRefresh} - > - Refresh - - + {canShowShip ? ( + <> + {resolvedShipPrimary === "merge" ? ( + { + void persistShipDefault("pr"); + if (hasPullRequest && prStatus?.url) { + void Linking.openURL(prStatus.url); + return; + } + prMutation.mutate(); + }} + > + {hasPullRequest ? "Open PR" : "Create PR"} + + ) : ( + { + void persistShipDefault("merge"); + mergeMutation.mutate(); + }} + > + Merge branch + + )} + + + ) : null} mergeFromBaseMutation.mutate()} > Merge from {baseRefLabel} - {mergeFromBaseDisabled && hasUncommittedChanges ? ( - Requires a clean working tree. - ) : null} - + pushMutation.mutate()} > Push branch - {pushDisabled && !(gitStatus?.hasRemote ?? false) ? ( - Remote 'origin' is not configured. - ) : null} + ) : null} + + + {isGit ? ( + + + {canShowCommit ? ( + commitMutation.mutate()} + disabled={commitDisabled} + > + {commitMutation.isPending ? ( + + ) : ( + Commit + )} + + ) : ( + + )} + + + + + + {diffMode === "uncommitted" ? "Working" : "Base"} + + + + + setDiffMode("uncommitted")} + > + Working + + setDiffMode("base")} + > + Base + + + + ) : null} @@ -1076,6 +1090,12 @@ const styles = StyleSheet.create((theme) => ({ flex: 1, minWidth: 0, }, + headerRight: { + flexDirection: "row", + alignItems: "center", + gap: theme.spacing[1], + flexShrink: 0, + }, branchLabel: { fontSize: theme.fontSize.sm, color: theme.colors.foreground, @@ -1104,7 +1124,9 @@ const styles = StyleSheet.create((theme) => ({ gap: theme.spacing[2], paddingHorizontal: theme.spacing[3], paddingTop: theme.spacing[2], - paddingBottom: theme.spacing[1], + paddingBottom: theme.spacing[3], + borderBottomWidth: 1, + borderBottomColor: theme.colors.border, }, toolbarLeft: { flex: 1, @@ -1136,6 +1158,9 @@ const styles = StyleSheet.create((theme) => ({ color: theme.colors.foreground, fontWeight: theme.fontWeight.medium, }, + buttonSpinner: { + height: theme.fontSize.xs * 1.4, + }, shipSplitButton: { flexDirection: "row", alignItems: "stretch", @@ -1148,7 +1173,7 @@ const styles = StyleSheet.create((theme) => ({ shipPrimaryButton: { paddingHorizontal: theme.spacing[3], paddingVertical: theme.spacing[2], - minWidth: 140, + justifyContent: "center", }, shipPrimaryButtonDisabled: { opacity: 0.6, @@ -1158,11 +1183,6 @@ const styles = StyleSheet.create((theme) => ({ color: theme.colors.foreground, fontWeight: theme.fontWeight.medium, }, - shipSecondaryText: { - marginTop: 2, - fontSize: theme.fontSize.xs, - color: theme.colors.foregroundMuted, - }, shipCaretButton: { width: 36, alignItems: "center", @@ -1373,16 +1393,14 @@ const styles = StyleSheet.create((theme) => ({ color: theme.colors.palette.red[500], }, additions: { - fontSize: theme.fontSize.sm, + fontSize: theme.fontSize.xs, fontWeight: theme.fontWeight.normal, color: theme.colors.palette.green[400], - fontFamily: Fonts.mono, }, deletions: { - fontSize: theme.fontSize.sm, + fontSize: theme.fontSize.xs, fontWeight: theme.fontWeight.normal, color: theme.colors.palette.red[500], - fontFamily: Fonts.mono, }, diffContent: { borderTopWidth: theme.borderWidth[1], diff --git a/packages/server/src/utils/checkout-git.ts b/packages/server/src/utils/checkout-git.ts index cd9984bac..db867d76c 100644 --- a/packages/server/src/utils/checkout-git.ts +++ b/packages/server/src/utils/checkout-git.ts @@ -485,11 +485,13 @@ export async function getCheckoutDiff( throw new Error(`Base ref mismatch: expected ${baseRef}, got ${compare.baseRef}`); } else { const normalizedBaseRef = normalizeLocalBranchRefName(baseRef); - const { stdout } = await execAsync(`git diff ${normalizedBaseRef}...HEAD`, { + // Diff base ref against working tree (includes uncommitted changes) + const { stdout: trackedDiff } = await execAsync(`git diff ${normalizedBaseRef}`, { cwd, env: READ_ONLY_GIT_ENV, }); - diff = stdout; + const untrackedDiff = await getUntrackedDiff(cwd); + diff = trackedDiff + untrackedDiff; } } diff --git a/scripts/dev.sh b/scripts/dev.sh index 630f3e618..b72ab5c2b 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -10,8 +10,8 @@ DAEMON_PORT=$(get-port 6767 6768 6769 6770 6771 6772 6773) METRO_PORT=$(get-port 8081 8082 8083 8084 8085 8086 8087) # Use a temporary PASEO_HOME to avoid conflicts between dev instances -export PASEO_HOME=$(mktemp -d "${TMPDIR:-/tmp}/paseo-dev.XXXXXX") -trap "rm -rf '$PASEO_HOME'" EXIT +# export PASEO_HOME=$(mktemp -d "${TMPDIR:-/tmp}/paseo-dev.XXXXXX") +# trap "rm -rf '$PASEO_HOME'" EXIT # Build CORS origins for this Expo instance CORS_ORIGINS="http://localhost:${METRO_PORT},http://127.0.0.1:${METRO_PORT}" @@ -24,7 +24,7 @@ echo " Paseo Dev" echo "══════════════════════════════════════════════════════" echo " Daemon: http://localhost:${DAEMON_PORT}" echo " Metro: http://localhost:${METRO_PORT}" -echo " Home: ${PASEO_HOME}" +# echo " Home: ${PASEO_HOME}" echo "══════════════════════════════════════════════════════" # Export for child processes (overrides .env values)