diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css
index 0c05fdee0a..cdc27e9a3a 100644
--- a/apps/web/app/globals.css
+++ b/apps/web/app/globals.css
@@ -92,6 +92,10 @@
--scrollbar-thumb-hover: oklch(0.66 0 0);
--scrollbar-track: var(--background);
--sidebar-ring: oklch(0.708 0 0);
+
+ /* Git diff colors - centralized for easy maintenance */
+ --git-addition: 16 185 129; /* emerald-500 */
+ --git-deletion: 244 63 94; /* rose-500 */
}
.dark {
@@ -129,6 +133,10 @@
--scrollbar-thumb-hover: oklch(0.62 0 0 / 0.8);
--scrollbar-track: var(--background);
--sidebar-ring: oklch(0.556 0 0);
+
+ /* Git diff colors - same as light mode for consistency */
+ --git-addition: 16 185 129; /* emerald-500 */
+ --git-deletion: 244 63 94; /* rose-500 */
}
@layer base {
diff --git a/apps/web/components/diff/diff-viewer.tsx b/apps/web/components/diff/diff-viewer.tsx
index 194e2fd864..db41f43409 100644
--- a/apps/web/components/diff/diff-viewer.tsx
+++ b/apps/web/components/diff/diff-viewer.tsx
@@ -430,6 +430,22 @@ export const DiffViewer = memo(function DiffViewer({
disableFileHeader: !showHeader,
lineDiffType: 'word',
overflow: wordWrap ? 'wrap' : 'scroll',
+ unsafeCSS: `
+ * {
+ background: transparent !important;
+ }
+
+ /* Reduce icon size */
+ [data-change-icon] {
+ width: 12px !important;
+ height: 12px !important;
+ }
+
+ /* Adjust header padding */
+ [data-diffs-header] {
+ padding-inline: 12px !important;
+ }
+ `,
}),
[globalViewMode, resolvedTheme, enableComments, showHeader, handleLineSelectionEnd, wordWrap]
);
@@ -476,6 +492,11 @@ export const DiffViewer = memo(function DiffViewer({
renderAnnotation={renderAnnotation}
renderHeaderMetadata={showHeader ? renderHeaderMetadata : undefined}
renderHoverUtility={renderHoverUtility}
+ style={{
+ '--diffs-addition-color-override': 'rgb(var(--git-addition))',
+ '--diffs-deletion-color-override': 'rgb(var(--git-deletion))',
+ '--diffs-font-size': '12px',
+ } as React.CSSProperties}
className={cn(
'rounded-md border border-border/50',
compact && 'text-xs'
diff --git a/apps/web/components/task/file-status-icon.tsx b/apps/web/components/task/file-status-icon.tsx
new file mode 100644
index 0000000000..7aee63ce94
--- /dev/null
+++ b/apps/web/components/task/file-status-icon.tsx
@@ -0,0 +1,44 @@
+'use client';
+
+import { IconPlus, IconCircleFilled, IconMinus } from '@tabler/icons-react';
+import type { FileInfo } from '@/lib/state/store';
+
+type FileStatusIconProps = {
+ status: FileInfo['status'];
+};
+
+export function FileStatusIcon({ status }: FileStatusIconProps) {
+ switch (status) {
+ case 'added':
+ case 'untracked':
+ return (
+
+
+
+ );
+ case 'modified':
+ return (
+
+
+
+ );
+ case 'deleted':
+ return (
+
+
+
+ );
+ case 'renamed':
+ return (
+
+
+
+ );
+ default:
+ return (
+
+
+
+ );
+ }
+}
diff --git a/apps/web/components/task/task-changes-panel.tsx b/apps/web/components/task/task-changes-panel.tsx
index b0868c0979..7fb9ddb4bb 100644
--- a/apps/web/components/task/task-changes-panel.tsx
+++ b/apps/web/components/task/task-changes-panel.tsx
@@ -24,6 +24,7 @@ import { useGitOperations } from '@/hooks/use-git-operations';
import { FileDiffViewer } from '@/components/diff';
import type { FileInfo } from '@/lib/state/slices';
import type { SelectedDiff } from './task-layout';
+import { FileStatusIcon } from './file-status-icon';
type TaskChangesPanelProps = {
selectedDiff: SelectedDiff | null;
@@ -88,15 +89,18 @@ const TaskChangesPanel = memo(function TaskChangesPanel({
if (!cumulativeDiff?.files || Object.keys(cumulativeDiff.files).length === 0) {
return [];
}
+ // Create a Set of uncommitted file paths for efficient lookup
+ const uncommittedPaths = new Set(uncommittedFiles.map(f => f.path));
+
return Object.entries(cumulativeDiff.files)
- .filter(([, file]) => file.diff) // Only include files with diffs
+ .filter(([path, file]) => file.diff && !uncommittedPaths.has(path)) // Exclude uncommitted files
.map(([path, file]) => ({
path,
diff: file.diff!,
additions: file.additions ?? 0,
deletions: file.deletions ?? 0,
}));
- }, [cumulativeDiff]);
+ }, [cumulativeDiff, uncommittedFiles]);
const selectedFile = selectedDiffPath && gitStatus?.files ? gitStatus.files[selectedDiffPath] : null;
// Prioritize current git status for uncommitted files, use provided content only for historical diffs
@@ -253,9 +257,12 @@ const TaskChangesPanel = memo(function TaskChangesPanel({
return (
-
- {file.path}
-
+
+
+
+ {file.path}
+
+
+{file.additions}
{' / '}
diff --git a/apps/web/components/task/task-files-panel.tsx b/apps/web/components/task/task-files-panel.tsx
index 0d4d23b1f8..1fe4c87b77 100644
--- a/apps/web/components/task/task-files-panel.tsx
+++ b/apps/web/components/task/task-files-panel.tsx
@@ -5,7 +5,6 @@ import {
IconArrowBackUp,
IconExternalLink,
IconPlus,
- IconCircleFilled,
IconMinus,
IconCheck,
IconChevronRight,
@@ -47,6 +46,7 @@ import {
hasUserSelectedFilesPanelTab,
setUserSelectedFilesPanelTab,
} from '@/lib/local-storage';
+import { FileStatusIcon } from './file-status-icon';
type TaskFilesPanelProps = {
onSelectDiff: (path: string, content?: string) => void;
@@ -56,42 +56,6 @@ type TaskFilesPanelProps = {
-const StatusIcon = ({ status }: { status: FileInfo['status'] }) => {
- switch (status) {
- case 'added':
- case 'untracked':
- return (
-
-
-
- );
- case 'modified':
- return (
-
-
-
- );
- case 'deleted':
- return (
-
-
-
- );
- case 'renamed':
- return (
-
-
-
- );
- default:
- return (
-
-
-
- );
- }
-};
-
const splitPath = (path: string) => {
const lastSlash = path.lastIndexOf('/');
if (lastSlash === -1) return { folder: '', file: path };
@@ -398,7 +362,7 @@ const TaskFilesPanel = memo(function TaskFilesPanel({ onSelectDiff, onOpenFile,
-
+
);
@@ -458,7 +422,7 @@ const TaskFilesPanel = memo(function TaskFilesPanel({ onSelectDiff, onOpenFile,
className="flex items-center gap-2 text-xs rounded px-1 py-0.5 hover:bg-muted/50 cursor-pointer"
onClick={() => onSelectDiff(path, file.diff)}
>
-
+
{folder}/
{fileName}
diff --git a/apps/web/components/task/task-top-bar.tsx b/apps/web/components/task/task-top-bar.tsx
index 656b4bd769..98942638a4 100644
--- a/apps/web/components/task/task-top-bar.tsx
+++ b/apps/web/components/task/task-top-bar.tsx
@@ -46,9 +46,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@kandev/ui/tooltip';
import { Popover, PopoverContent, PopoverTrigger } from '@kandev/ui/popover';
import { Checkbox } from '@kandev/ui/checkbox';
import { Label } from '@kandev/ui/label';
-import { CommitStatBadge, LineStat } from '@/components/diff-stat';
+import { CommitStatBadge } from '@/components/diff-stat';
import { useSessionGitStatus } from '@/hooks/domains/session/use-session-git-status';
-import { useSessionCommits } from '@/hooks/domains/session/use-session-commits';
import { useGitOperations } from '@/hooks/use-git-operations';
import type { FileInfo } from '@/lib/state/slices';
import { formatUserHomePath } from '@/lib/utils';
@@ -105,7 +104,6 @@ const TaskTopBar = memo(function TaskTopBar({
const router = useRouter();
const { toast } = useToast();
const gitStatus = useSessionGitStatus(activeSessionId ?? null);
- const { commits } = useSessionCommits(activeSessionId ?? null);
const { pull, push, rebase, merge, commit, createPR, isLoading: isGitLoading } = useGitOperations(activeSessionId ?? null);
const { open: openFolder, isLoading: isOpenFolderLoading } = useOpenSessionFolder(activeSessionId);
@@ -128,14 +126,6 @@ const TaskTopBar = memo(function TaskTopBar({
}
}
- // Calculate cumulative additions and deletions from commits.
- const commitAdditions = commits.reduce((sum, c) => sum + c.insertions, 0);
- const commitDeletions = commits.reduce((sum, c) => sum + c.deletions, 0);
-
- // Combined total (uncommitted + commits)
- const totalAdditions = uncommittedAdditions + commitAdditions;
- const totalDeletions = uncommittedDeletions + commitDeletions;
-
const handleGitOperation = useCallback(async (
operation: () => Promise<{ success: boolean; output: string; error?: string; conflict_files?: string[] }>,
operationName: string
@@ -391,20 +381,6 @@ const TaskTopBar = memo(function TaskTopBar({
)}
- {/* Git Status: Total Lines Changed (uncommitted + commits) */}
- {(totalAdditions > 0 || totalDeletions > 0) && (
-
-
-
-
-
-
-
- Total changes{commits.length > 0 ? ` (${commits.length} commit${commits.length !== 1 ? 's' : ''}${uncommittedAdditions > 0 || uncommittedDeletions > 0 ? ' + uncommitted' : ''})` : ''}
-
-
- )}
-
{DEBUG_UI && onToggleDebugOverlay && (