chore: remove unused FE files and deps (#720)

* remove unused FE files and deps

* update lock file
This commit is contained in:
Gabriel Gordon-Hall
2025-09-15 13:01:24 +01:00
committed by GitHub
parent a3b705d559
commit 47dc2cd78b
15 changed files with 1 additions and 861 deletions

View File

@@ -22,12 +22,9 @@
"@dnd-kit/modifiers": "^9.0.0",
"@git-diff-view/file": "^0.0.30",
"@git-diff-view/react": "^0.0.30",
"@microsoft/fetch-event-source": "^2.0.1",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-portal": "^1.1.9",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.12",
"@radix-ui/react-tooltip": "^1.2.7",
@@ -36,24 +33,19 @@
"@sentry/vite-plugin": "^3.5.0",
"@tailwindcss/typography": "^0.5.16",
"@tanstack/react-query": "^5.85.5",
"@tanstack/react-query-devtools": "^5.85.5",
"@types/react-window": "^1.8.8",
"@uiw/react-codemirror": "^4.25.1",
"@virtuoso.dev/message-list": "^1.13.3",
"class-variance-authority": "^0.7.0",
"click-to-react-component": "^1.1.2",
"clsx": "^2.0.0",
"diff": "^8.0.2",
"embla-carousel-react": "^8.6.0",
"fancy-ansi": "^0.1.3",
"idb": "^8.0.3",
"lucide-react": "^0.539.0",
"react": "^18.2.0",
"react-diff-viewer-continued": "^3.4.0",
"react-dom": "^18.2.0",
"react-markdown": "^10.1.0",
"react-router-dom": "^6.8.1",
"react-use-measure": "^2.1.7",
"react-virtuoso": "^4.14.0",
"react-window": "^1.8.11",
"rfc6902": "^5.1.2",
@@ -84,4 +76,4 @@
"typescript": "^5.9.2",
"vite": "^5.0.8"
}
}
}

View File

@@ -1,35 +0,0 @@
import { useKeyboardShortcuts } from '@/lib/keyboard-shortcuts';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
export function KeyboardShortcutsDemo() {
const shortcuts = useKeyboardShortcuts({
navigate: undefined,
currentPath: '/demo',
hasOpenDialog: false,
closeDialog: () => {},
onC: () => {},
});
return (
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle>Keyboard Shortcuts</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
{Object.values(shortcuts).map((shortcut) => (
<div
key={shortcut.key}
className="flex justify-between items-center"
>
<span className="text-sm">{shortcut.description}</span>
<kbd className="px-2 py-1 text-xs bg-muted rounded border">
{shortcut.key === 'KeyC' ? 'C' : shortcut.key}
</kbd>
</div>
))}
</div>
</CardContent>
</Card>
);
}

View File

@@ -1,45 +0,0 @@
import { memo } from 'react';
import type { UnifiedLogEntry } from '@/types/logs';
import type { NormalizedEntry } from 'shared/types';
import StdoutEntry from './StdoutEntry';
import StderrEntry from './StderrEntry';
import DisplayConversationEntry from '@/components/NormalizedConversation/DisplayConversationEntry';
interface LogEntryRowProps {
entry: UnifiedLogEntry;
index: number;
isCollapsed?: boolean;
onToggleCollapse?: (processId: string) => void;
onRestore?: (processId: string) => void;
restoreProcessId?: string;
restoreDisabled?: boolean;
restoreDisabledReason?: string;
}
function LogEntryRow({ entry, index }: LogEntryRowProps) {
switch (entry.channel) {
case 'stdout':
return <StdoutEntry content={entry.payload as string} />;
case 'stderr':
return <StderrEntry content={entry.payload as string} />;
case 'normalized':
return (
<div className="my-4">
<DisplayConversationEntry
entry={entry.payload as NormalizedEntry}
expansionKey={`${entry.processId}:${index}`}
diffDeletable={false}
/>
</div>
);
default:
return (
<div className="text-destructive text-xs">
Unknown log type: {entry.channel}
</div>
);
}
}
// Memoize to optimize react-window performance
export default memo(LogEntryRow);

View File

@@ -1,11 +0,0 @@
import RawLogText from '@/components/common/RawLogText';
interface StderrEntryProps {
content: string;
}
function StderrEntry({ content }: StderrEntryProps) {
return <RawLogText content={content} channel="stderr" as="span" />;
}
export default StderrEntry;

View File

@@ -1,11 +0,0 @@
import RawLogText from '@/components/common/RawLogText';
interface StdoutEntryProps {
content: string;
}
function StdoutEntry({ content }: StdoutEntryProps) {
return <RawLogText content={content} channel="stdout" as="span" />;
}
export default StdoutEntry;

View File

@@ -1,20 +0,0 @@
import { useState } from 'react';
import { ProjectList } from './project-list';
import { ProjectDetail } from './project-detail';
export function ProjectsPage() {
const [selectedProjectId, setSelectedProjectId] = useState<string | null>(
null
);
if (selectedProjectId) {
return (
<ProjectDetail
projectId={selectedProjectId}
onBack={() => setSelectedProjectId(null)}
/>
);
}
return <ProjectList />;
}

View File

@@ -1,26 +0,0 @@
import DisplayConversationEntry from '@/components/NormalizedConversation/DisplayConversationEntry';
import { useNormalizedLogs } from '@/hooks/useNormalizedLogs';
import { ExecutionProcess } from 'shared/types';
interface ConversationExecutionLogsProps {
executionProcess: ExecutionProcess;
}
const ConversationExecutionLogs = ({
executionProcess,
}: ConversationExecutionLogsProps) => {
const { entries } = useNormalizedLogs(executionProcess.id);
console.log('DEBUG7', entries);
return entries.map((entry, i) => {
return (
<DisplayConversationEntry
expansionKey={`expansion-${executionProcess.id}-${i}`}
entry={entry}
/>
);
});
};
export default ConversationExecutionLogs;

View File

@@ -1,37 +0,0 @@
import { Moon, Sun } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { useTheme } from '@/components/theme-provider';
import { ThemeMode } from 'shared/types';
export function ThemeToggle() {
const { setTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme(ThemeMode.LIGHT)}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme(ThemeMode.DARK)}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme(ThemeMode.SYSTEM)}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -1,25 +0,0 @@
import { cn } from '@/lib/utils';
export interface ChipProps {
children: React.ReactNode;
dotColor?: string;
className?: string;
}
export function Chip({
children,
dotColor = 'bg-gray-400',
className,
}: ChipProps) {
return (
<span
className={cn(
'inline-flex items-center gap-2 px-2 py-1 rounded-full text-xs font-medium bg-muted text-muted-foreground',
className
)}
>
<span className={cn('w-2 h-2 rounded-full', dotColor)} />
{children}
</span>
);
}

View File

@@ -1,31 +0,0 @@
'use client';
import * as React from 'react';
import * as SeparatorPrimitive from '@radix-ui/react-separator';
import { cn } from '@/lib/utils';
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(
(
{ className, orientation = 'horizontal', decorative = true, ...props },
ref
) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
'shrink-0 bg-border',
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
className
)}
{...props}
/>
)
);
Separator.displayName = SeparatorPrimitive.Root.displayName;
export { Separator };

View File

@@ -1,117 +0,0 @@
import * as React from 'react';
import { cn } from '@/lib/utils';
const Table = React.forwardRef<
HTMLTableElement,
React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table
ref={ref}
className={cn('w-full caption-bottom text-sm', className)}
{...props}
/>
</div>
));
Table.displayName = 'Table';
const TableHeader = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
));
TableHeader.displayName = 'TableHeader';
const TableBody = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody
ref={ref}
className={cn('[&_tr:last-child]:border-0', className)}
{...props}
/>
));
TableBody.displayName = 'TableBody';
const TableFooter = React.forwardRef<
HTMLTableSectionElement,
React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn(
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
className
)}
{...props}
/>
));
TableFooter.displayName = 'TableFooter';
const TableRow = React.forwardRef<
HTMLTableRowElement,
React.HTMLAttributes<HTMLTableRowElement>
>(({ className, ...props }, ref) => (
<tr
ref={ref}
className={cn(
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
className
)}
{...props}
/>
));
TableRow.displayName = 'TableRow';
const TableHead = React.forwardRef<
HTMLTableCellElement,
React.ThHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<th
ref={ref}
className={cn(
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
className
)}
{...props}
/>
));
TableHead.displayName = 'TableHead';
const TableCell = React.forwardRef<
HTMLTableCellElement,
React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<td
ref={ref}
className={cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', className)}
{...props}
/>
));
TableCell.displayName = 'TableCell';
const TableCaption = React.forwardRef<
HTMLTableCaptionElement,
React.HTMLAttributes<HTMLTableCaptionElement>
>(({ className, ...props }, ref) => (
<caption
ref={ref}
className={cn('mt-4 text-sm text-muted-foreground', className)}
{...props}
/>
));
TableCaption.displayName = 'TableCaption';
export {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
};

View File

@@ -1,71 +0,0 @@
import {
createContext,
useContext,
useState,
useCallback,
ReactNode,
useMemo,
} from 'react';
import type { TaskAttempt, TaskWithAttemptStatus } from 'shared/types';
interface CreatePRDialogData {
attempt: TaskAttempt;
task: TaskWithAttemptStatus;
projectId: string;
}
interface CreatePRDialogState {
isOpen: boolean;
data: CreatePRDialogData | null;
showCreatePRDialog: (data: CreatePRDialogData) => void;
closeCreatePRDialog: () => void;
}
const CreatePRDialogContext = createContext<CreatePRDialogState | null>(null);
interface CreatePRDialogProviderProps {
children: ReactNode;
}
export function CreatePRDialogProvider({
children,
}: CreatePRDialogProviderProps) {
const [isOpen, setIsOpen] = useState(false);
const [data, setData] = useState<CreatePRDialogData | null>(null);
const showCreatePRDialog = useCallback((data: CreatePRDialogData) => {
setData(data);
setIsOpen(true);
}, []);
const closeCreatePRDialog = useCallback(() => {
setIsOpen(false);
setData(null);
}, []);
const value = useMemo(
() => ({
isOpen,
data,
showCreatePRDialog,
closeCreatePRDialog,
}),
[isOpen, data, showCreatePRDialog, closeCreatePRDialog]
);
return (
<CreatePRDialogContext.Provider value={value}>
{children}
</CreatePRDialogContext.Provider>
);
}
export function useCreatePRDialog(): CreatePRDialogState {
const context = useContext(CreatePRDialogContext);
if (!context) {
throw new Error(
'useCreatePRDialog must be used within a CreatePRDialogProvider'
);
}
return context;
}

View File

@@ -1,58 +0,0 @@
// useNormalizedLogs.ts
import { useCallback, useMemo } from 'react';
import { useJsonPatchStream } from './useJsonPatchStream';
import { NormalizedEntry } from 'shared/types';
type EntryType = { type: string };
export interface NormalizedEntryContent {
timestamp: string | null;
entry_type: EntryType;
content: string;
metadata: Record<string, unknown> | null;
}
export interface NormalizedLogsState {
entries: NormalizedEntry[];
session_id: string | null;
executor_type: string;
prompt: string | null;
summary: string | null;
}
interface UseNormalizedLogsResult {
entries: NormalizedEntry[];
state: NormalizedLogsState | undefined;
isLoading: boolean;
isConnected: boolean;
error: string | null;
}
export const useNormalizedLogs = (
processId: string,
enabled: boolean = true
): UseNormalizedLogsResult => {
const endpoint = `/api/execution-processes/${encodeURIComponent(processId)}/normalized-logs`;
const initialData = useCallback<() => NormalizedLogsState>(
() => ({
entries: [],
session_id: null,
executor_type: '',
prompt: null,
summary: null,
}),
[]
);
const { data, isConnected, error } = useJsonPatchStream<NormalizedLogsState>(
endpoint,
Boolean(processId) && enabled,
initialData
);
const entries = useMemo(() => data?.entries ?? [], [data?.entries]);
const isLoading = !data && !error;
return { entries, state: data, isLoading, isConnected, error };
};

View File

@@ -1,92 +0,0 @@
import { useCallback } from 'react';
import type { ProcessStartPayload } from '@/types/logs';
import type { Operation } from 'rfc6902';
import { useJsonPatchStream } from './useJsonPatchStream';
interface ProcessConversationData {
entries: any[]; // Mixed types: NormalizedEntry | ProcessStartPayload | PatchType
session_id: string | null;
executor_type: string;
prompt: string | null;
summary: string | null;
}
interface UseProcessConversationResult {
entries: any[]; // Mixed types like the original
isConnected: boolean;
error: string | null;
}
export const useProcessConversation = (
processId: string,
enabled: boolean
): UseProcessConversationResult => {
const endpoint = processId
? `/api/execution-processes/${processId}/normalized-logs`
: undefined;
const initialData = useCallback(
(): ProcessConversationData => ({
entries: [],
session_id: null,
executor_type: '',
prompt: null,
summary: null,
}),
[]
);
const injectInitialEntry = useCallback(
(data: ProcessConversationData) => {
if (processId) {
// Inject process start marker as the first entry
const processStartPayload: ProcessStartPayload = {
processId: processId,
runReason: 'Manual', // Default value since we don't have process details here
startedAt: new Date().toISOString(),
status: 'running',
};
const processStartEntry = {
type: 'PROCESS_START' as const,
content: processStartPayload,
};
data.entries.push(processStartEntry);
}
},
[processId]
);
const deduplicatePatches = useCallback((patches: Operation[]) => {
const processedEntries = new Set<number>();
return patches.filter((patch: any) => {
// Extract entry index from path like "/entries/123"
const match = patch.path?.match(/^\/entries\/(\d+)$/);
if (match && patch.op === 'add') {
const entryIndex = parseInt(match[1], 10);
if (processedEntries.has(entryIndex)) {
return false; // Already processed
}
processedEntries.add(entryIndex);
}
// Always allow replace operations and non-entry patches
return true;
});
}, []);
const { data, isConnected, error } = useJsonPatchStream(
endpoint,
enabled && !!processId,
initialData,
{
injectInitialEntry,
deduplicatePatches,
}
);
const entries = data?.entries || [];
return { entries, isConnected, error };
};