import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { ReactElement, ReactNode } from "react"; import { View, Text, Pressable, Modal, TextInput, ActivityIndicator, useWindowDimensions, ScrollView, Platform, } from "react-native"; import { StyleSheet, UnistylesRuntime } from "react-native-unistyles"; import { BottomSheetModal, BottomSheetScrollView, BottomSheetBackdrop, BottomSheetTextInput, BottomSheetBackgroundProps, } from "@gorhom/bottom-sheet"; import Animated from "react-native-reanimated"; import { ChevronDown, ChevronRight, Pencil, Check, X } from "lucide-react-native"; import { theme as defaultTheme } from "@/styles/theme"; import type { AgentMode, AgentModelDefinition, AgentProvider, } from "@server/server/agent/agent-sdk-types"; import type { AgentProviderDefinition } from "@server/server/agent/provider-manifest"; type DropdownTriggerRenderProps = { label: string; value: string; placeholder: string; onPress: () => void; disabled?: boolean; errorMessage?: string | null; warningMessage?: string | null; helperText?: string | null; }; type DropdownTriggerRenderer = (props: DropdownTriggerRenderProps) => ReactNode; interface DropdownFieldProps { label: string; value: string; placeholder: string; onPress: () => void; disabled?: boolean; errorMessage?: string | null; warningMessage?: string | null; helperText?: string | null; renderTrigger?: DropdownTriggerRenderer; } export function DropdownField({ label, value, placeholder, onPress, disabled, errorMessage, warningMessage, helperText, renderTrigger, }: DropdownFieldProps): ReactElement { if (renderTrigger) { return ( <> {renderTrigger({ label, value, placeholder, onPress, disabled, errorMessage, warningMessage, helperText, })} ); } return ( {label} {value || placeholder} {errorMessage ? {errorMessage} : null} {warningMessage ? {warningMessage} : null} {!errorMessage && helperText ? ( {helperText} ) : null} ); } interface SelectFieldProps { label: string; value: string; placeholder?: string; onPress: () => void; disabled?: boolean; errorMessage?: string | null; warningMessage?: string | null; helperText?: string | null; controlRef?: React.RefObject; } export function SelectField({ label, value, placeholder, onPress, disabled, errorMessage, warningMessage, helperText, controlRef, }: SelectFieldProps): ReactElement { return ( {label} {value || placeholder || "Select..."} {errorMessage ? {errorMessage} : null} {warningMessage ? {warningMessage} : null} {!errorMessage && !warningMessage && helperText ? ( {helperText} ) : null} ); } interface DropdownSheetProps { title: string; visible: boolean; onClose: () => void; children: ReactNode; } function DropdownSheetBackground({ style }: BottomSheetBackgroundProps) { return ( ); } export function DropdownSheet({ title, visible, onClose, children, }: DropdownSheetProps): ReactElement { const bottomSheetRef = useRef(null); const snapPoints = useMemo(() => ["60%", "90%"], []); useEffect(() => { if (visible) { bottomSheetRef.current?.present(); } else { bottomSheetRef.current?.dismiss(); } }, [visible]); const handleSheetChange = useCallback( (index: number) => { if (index === -1) { onClose(); } }, [onClose] ); const renderBackdrop = useCallback( (props: React.ComponentProps) => ( ), [] ); return ( {title} {children} ); } interface AdaptiveSelectProps { title: string; visible: boolean; onClose: () => void; children: ReactNode; anchorRef: React.RefObject; } export function AdaptiveSelect({ title, visible, onClose, children, anchorRef, }: AdaptiveSelectProps): ReactElement { const isMobile = UnistylesRuntime.breakpoint === "xs" || UnistylesRuntime.breakpoint === "sm"; const { width: windowWidth, height: windowHeight } = useWindowDimensions(); const bottomSheetRef = useRef(null); const snapPoints = useMemo(() => ["60%", "90%"], []); const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0, }); useEffect(() => { if (!visible || isMobile) { return; } const anchor = anchorRef.current; if (!anchor) { return; } anchor.measureInWindow((x, y, width, height) => { const verticalOffset = 4; const horizontalMargin = 16; const maxDropdownHeight = 400; let top = y + height + verticalOffset; const left = Math.max(horizontalMargin, Math.min(x, windowWidth - width - horizontalMargin)); if (top + maxDropdownHeight > windowHeight - horizontalMargin) { top = y - maxDropdownHeight - verticalOffset; if (top < horizontalMargin) { top = y + height + verticalOffset; } } setDropdownPosition({ top, left, width }); }); }, [visible, isMobile, anchorRef, windowWidth, windowHeight]); useEffect(() => { if (!isMobile) return; if (visible) { bottomSheetRef.current?.present(); } else { bottomSheetRef.current?.dismiss(); } }, [visible, isMobile]); const handleSheetChange = useCallback( (index: number) => { if (index === -1) { onClose(); } }, [onClose] ); const renderBackdrop = useCallback( (props: React.ComponentProps) => ( ), [] ); if (isMobile) { return ( {title} {children} ); } return ( {children} ); } interface ComboSelectOption { id: string; label: string; description?: string; } interface ComboSelectProps { label: string; title: string; value: string; options: ComboSelectOption[]; placeholder?: string; disabled?: boolean; allowCustomValue?: boolean; isLoading?: boolean; onSelect: (id: string) => void; } export function ComboSelect({ label, title, value, options, placeholder, disabled, allowCustomValue = false, isLoading, onSelect, }: ComboSelectProps): ReactElement { const [isOpen, setIsOpen] = useState(false); const anchorRef = useRef(null); const [searchQuery, setSearchQuery] = useState(""); const selectedOption = options.find((opt) => opt.id === value); const displayValue = selectedOption?.label ?? (value || ""); const handleOpen = useCallback(() => setIsOpen(true), []); const handleClose = useCallback(() => { setIsOpen(false); setSearchQuery(""); }, []); useEffect(() => { if (isOpen) { setSearchQuery(""); } }, [isOpen]); const normalizedSearch = searchQuery.trim().toLowerCase(); const filteredOptions = useMemo(() => { if (!normalizedSearch) { return options; } return options.filter( (opt) => opt.label.toLowerCase().includes(normalizedSearch) || opt.id.toLowerCase().includes(normalizedSearch) || opt.description?.toLowerCase().includes(normalizedSearch) ); }, [options, normalizedSearch]); const hasMatches = filteredOptions.length > 0; const sanitizedSearchValue = searchQuery.trim(); const showCustomOption = allowCustomValue && sanitizedSearchValue.length > 0 && !options.some( (opt) => opt.id.toLowerCase() === sanitizedSearchValue.toLowerCase() || opt.label.toLowerCase() === sanitizedSearchValue.toLowerCase() ); const handleSelect = useCallback( (id: string) => { onSelect(id); handleClose(); }, [handleClose, onSelect] ); return ( <> {Platform.OS === "web" ? ( ) : ( )} {showCustomOption ? ( handleSelect(sanitizedSearchValue)} > {`Use "${sanitizedSearchValue}"`} ) : null} {hasMatches ? ( {filteredOptions.map((opt) => { const isSelected = opt.id === value; return ( handleSelect(opt.id)} > {opt.label} {opt.description ? ( {opt.description} ) : null} ); })} ) : !showCustomOption ? ( No options match your search. ) : null} {isLoading ? ( ) : null} ); } interface CompactSelectFieldProps { label: string; value: string; placeholder?: string; onPress: () => void; disabled?: boolean; isLoading?: boolean; controlRef?: React.RefObject; } function CompactSelectField({ label, value, placeholder, onPress, disabled, isLoading, controlRef, }: CompactSelectFieldProps): ReactElement { return ( {label} {isLoading ? ( ) : ( {value || placeholder || "Select..."} )} ); } interface AgentConfigRowProps { providerDefinitions: AgentProviderDefinition[]; selectedProvider: AgentProvider; onSelectProvider: (provider: AgentProvider) => void; modeOptions: AgentMode[]; selectedMode: string; onSelectMode: (modeId: string) => void; models: AgentModelDefinition[]; selectedModel: string; isModelLoading: boolean; onSelectModel: (modelId: string) => void; disabled?: boolean; } export function AgentConfigRow({ providerDefinitions, selectedProvider, onSelectProvider, modeOptions, selectedMode, onSelectMode, models, selectedModel, isModelLoading, onSelectModel, disabled, }: AgentConfigRowProps): ReactElement { const providerOptions: ComboSelectOption[] = useMemo( () => providerDefinitions.map((def) => ({ id: def.id, label: def.label, description: def.description, })), [providerDefinitions] ); const modeSelectOptions: ComboSelectOption[] = useMemo(() => { if (modeOptions.length === 0) { return [{ id: "", label: "Default", description: "Provider default mode" }]; } return modeOptions.map((mode) => ({ id: mode.id, label: mode.label, description: mode.description, })); }, [modeOptions]); const modelSelectOptions: ComboSelectOption[] = useMemo(() => { const opts: ComboSelectOption[] = [ { id: "", label: "Auto", description: "Provider default model" }, ]; for (const model of models) { opts.push({ id: model.id, label: model.label, description: model.description, }); } return opts; }, [models]); const effectiveSelectedMode = selectedMode || (modeOptions.length > 0 ? modeOptions[0]?.id : ""); return ( ); } interface AssistantDropdownProps { providerDefinitions: AgentProviderDefinition[]; selectedProvider: AgentProvider; disabled: boolean; onSelect: (provider: AgentProvider) => void; } export function AssistantDropdown({ providerDefinitions, selectedProvider, disabled, onSelect, }: AssistantDropdownProps): ReactElement { const [isOpen, setIsOpen] = useState(false); const anchorRef = useRef(null); const selectedDefinition = providerDefinitions.find( (definition) => definition.id === selectedProvider ); const handleOpen = useCallback(() => setIsOpen(true), []); const handleClose = useCallback(() => setIsOpen(false), []); return ( <> {providerDefinitions.map((definition) => { const isSelected = definition.id === selectedProvider; return ( { onSelect(definition.id); handleClose(); }} > {definition.label} {definition.description ? ( {definition.description} ) : null} ); })} ); } interface PermissionsDropdownProps { modeOptions: AgentMode[]; selectedMode: string; disabled: boolean; onSelect: (modeId: string) => void; } export function PermissionsDropdown({ modeOptions, selectedMode, disabled, onSelect, }: PermissionsDropdownProps): ReactElement { const [isOpen, setIsOpen] = useState(false); const anchorRef = useRef(null); const hasOptions = modeOptions.length > 0; const selectedModeLabel = hasOptions ? modeOptions.find((mode) => mode.id === selectedMode)?.label ?? modeOptions[0]?.label ?? "Default" : "Automatic"; const handleOpen = useCallback(() => { if (hasOptions) { setIsOpen(true); } }, [hasOptions]); const handleClose = useCallback(() => setIsOpen(false), []); return ( <> {hasOptions ? ( {modeOptions.map((mode) => { const isSelected = mode.id === selectedMode; return ( { onSelect(mode.id); handleClose(); }} > {mode.label} {mode.description ? ( {mode.description} ) : null} ); })} ) : null} ); } interface ModelDropdownProps { models: AgentModelDefinition[]; selectedModel: string; isLoading: boolean; error: string | null; onSelect: (modelId: string) => void; onClear: () => void; onRefresh: () => void; } export function ModelDropdown({ models, selectedModel, isLoading, error, onSelect, onClear, onRefresh, }: ModelDropdownProps): ReactElement { const [isOpen, setIsOpen] = useState(false); const anchorRef = useRef(null); const selectedLabel = selectedModel ? models.find((model) => model.id === selectedModel)?.label ?? selectedModel : "Automatic"; const placeholder = isLoading && models.length === 0 ? "Loading..." : "Automatic"; const helperText = error ? undefined : isLoading ? "Fetching available models..." : models.length === 0 ? "This assistant did not expose selectable models." : undefined; const handleOpen = useCallback(() => setIsOpen(true), []); const handleClose = useCallback(() => setIsOpen(false), []); return ( <> { onClear(); handleClose(); }} > Automatic (provider default) Let the assistant pick the recommended model. {models.map((model) => { const isSelected = model.id === selectedModel; return ( { onSelect(model.id); handleClose(); }} > {model.label} {model.description ? ( {model.description} ) : null} ); })} { onRefresh(); }} > Refresh models Request the latest catalog from the provider. {isLoading ? ( ) : null} ); } interface WorkingDirectoryDropdownProps { workingDir: string; errorMessage: string; disabled: boolean; suggestedPaths: string[]; onSelectPath: (value: string) => void; } export function WorkingDirectoryDropdown({ workingDir, errorMessage, disabled, suggestedPaths, onSelectPath, }: WorkingDirectoryDropdownProps): ReactElement { const [isOpen, setIsOpen] = useState(false); const anchorRef = useRef(null); const [searchQuery, setSearchQuery] = useState(""); const handleOpen = useCallback(() => setIsOpen(true), []); const handleClose = useCallback(() => setIsOpen(false), []); useEffect(() => { if (isOpen) { setSearchQuery(""); } }, [isOpen]); const normalizedSearch = searchQuery.trim().toLowerCase(); const filteredPaths = useMemo(() => { if (!normalizedSearch) { return suggestedPaths; } return suggestedPaths.filter((path) => path.toLowerCase().includes(normalizedSearch) ); }, [suggestedPaths, normalizedSearch]); const hasSuggestedPaths = suggestedPaths.length > 0; const hasMatches = filteredPaths.length > 0; const sanitizedSearchValue = searchQuery.trim(); const showCustomOption = sanitizedSearchValue.length > 0; const handleSelect = useCallback( (path: string) => { onSelectPath(path); handleClose(); }, [handleClose, onSelectPath] ); return ( <> {Platform.OS === "web" ? ( ) : ( )} {!hasSuggestedPaths && !showCustomOption ? ( We'll suggest directories from agents on this host once they exist. ) : null} {showCustomOption ? ( handleSelect(sanitizedSearchValue)} > {`Use "${sanitizedSearchValue}"`} Launch the agent in this directory ) : null} {hasMatches ? ( {filteredPaths.map((path) => { const isActive = path === workingDir; return ( handleSelect(path)} > {path} ); })} ) : hasSuggestedPaths ? ( No agent directories match your search. ) : null} ); } interface ToggleRowProps { label: string; description?: string; value: boolean; onToggle: (value: boolean) => void; disabled?: boolean; } export function ToggleRow({ label, description, value, onToggle, disabled, }: ToggleRowProps): ReactElement { return ( { if (!disabled) { onToggle(!value); } }} style={[styles.toggleRow, disabled && styles.toggleRowDisabled]} > {value ? : null} {label} {description ? ( {description} ) : null} ); } export interface GitOptionsSectionProps { useWorktree: boolean; onUseWorktreeChange: (value: boolean) => void; worktreeSlug: string; currentBranch: string | null; baseBranch: string; onBaseBranchChange: (value: string) => void; branches: Array<{ name: string; isCurrent: boolean }>; status: "idle" | "loading" | "ready" | "error"; repoError: string | null; gitValidationError: string | null; baseBranchError: string | null; } export function GitOptionsSection({ useWorktree, onUseWorktreeChange, worktreeSlug, currentBranch, baseBranch, onBaseBranchChange, branches, status, repoError, gitValidationError, baseBranchError, }: GitOptionsSectionProps): ReactElement { const isLoading = status === "loading"; const [isEditingBranch, setIsEditingBranch] = useState(false); const [editedBranch, setEditedBranch] = useState(baseBranch); const inputRef = useRef(null); useEffect(() => { setEditedBranch(baseBranch); }, [baseBranch]); useEffect(() => { if (isEditingBranch) { inputRef.current?.focus(); } }, [isEditingBranch]); const handleStartEdit = useCallback(() => { setEditedBranch(baseBranch); setIsEditingBranch(true); }, [baseBranch]); const handleConfirmEdit = useCallback(() => { const trimmed = editedBranch.trim(); if (trimmed) { onBaseBranchChange(trimmed); } setIsEditingBranch(false); }, [editedBranch, onBaseBranchChange]); const handleCancelEdit = useCallback(() => { setEditedBranch(baseBranch); setIsEditingBranch(false); }, [baseBranch]); const displayBranch = baseBranch || currentBranch || "HEAD"; return ( onUseWorktreeChange(!useWorktree)} disabled={isLoading} style={[styles.worktreeToggle, isLoading && styles.worktreeToggleDisabled]} > {useWorktree ? : null} Create worktree {isLoading ? "Inspecting repository…" : useWorktree && worktreeSlug ? `Will create: ${worktreeSlug}` : currentBranch ? `Run isolated from ${currentBranch}` : "Run in an isolated directory"} {useWorktree ? ( Base branch: {isEditingBranch ? ( ) : ( {displayBranch} )} ) : null} {baseBranchError ? ( {baseBranchError} ) : null} {repoError ? ( {repoError} ) : null} {gitValidationError ? ( {gitValidationError} ) : null} ); } const styles = StyleSheet.create((theme) => ({ formSection: { gap: theme.spacing[3], }, label: { color: theme.colors.foreground, fontSize: theme.fontSize.sm, fontWeight: theme.fontWeight.semibold, }, dropdownControl: { flexDirection: "row", alignItems: "center", gap: theme.spacing[3], backgroundColor: theme.colors.surface0, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, borderRadius: theme.borderRadius.lg, paddingVertical: theme.spacing[3], paddingHorizontal: theme.spacing[4], }, dropdownControlDisabled: { opacity: theme.opacity[50], }, dropdownValue: { flex: 1, color: theme.colors.foreground, fontSize: theme.fontSize.base, }, dropdownPlaceholder: { flex: 1, color: theme.colors.foregroundMuted, fontSize: theme.fontSize.base, }, dropdownSearchInput: { borderRadius: theme.borderRadius.md, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, backgroundColor: theme.colors.surface0, paddingHorizontal: theme.spacing[3], paddingVertical: theme.spacing[2], color: theme.colors.foreground, }, bottomSheetBackground: { backgroundColor: theme.colors.surface2, borderTopLeftRadius: theme.borderRadius["2xl"], borderTopRightRadius: theme.borderRadius["2xl"], }, bottomSheetHandle: { backgroundColor: theme.colors.palette.zinc[600], }, bottomSheetHeader: { paddingHorizontal: theme.spacing[6], paddingBottom: theme.spacing[2], }, dropdownSheetOverlay: { flex: 1, justifyContent: "flex-end", }, dropdownSheetBackdrop: { position: "absolute", top: 0, right: 0, bottom: 0, left: 0, backgroundColor: theme.colors.palette.gray[900], opacity: 0.45, }, dropdownSheetContainer: { backgroundColor: theme.colors.surface2, borderTopLeftRadius: theme.borderRadius["2xl"], borderTopRightRadius: theme.borderRadius["2xl"], paddingTop: theme.spacing[4], paddingHorizontal: theme.spacing[6], paddingBottom: theme.spacing[6] + theme.spacing[2], maxHeight: 560, width: "100%", }, dropdownSheetHandle: { width: 56, height: 4, borderRadius: theme.borderRadius.full, backgroundColor: theme.colors.border, alignSelf: "center", marginBottom: theme.spacing[3], }, dropdownSheetTitle: { fontSize: theme.fontSize.lg, fontWeight: theme.fontWeight.semibold, color: theme.colors.foreground, textAlign: "center", }, dropdownSheetScrollContent: { paddingBottom: theme.spacing[8], paddingHorizontal: theme.spacing[1], }, dropdownSheetList: { marginTop: theme.spacing[3], }, dropdownSheetOption: { paddingVertical: theme.spacing[3], paddingHorizontal: theme.spacing[4], borderRadius: theme.borderRadius.lg, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, backgroundColor: theme.colors.surface0, marginBottom: theme.spacing[2], }, dropdownSheetOptionSelected: { borderColor: theme.colors.palette.blue[400], backgroundColor: "rgba(59, 130, 246, 0.18)", }, dropdownSheetOptionLabel: { color: theme.colors.foreground, fontWeight: theme.fontWeight.semibold, }, dropdownSheetOptionDescription: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, marginTop: theme.spacing[1], }, dropdownSheetLoading: { alignItems: "center", paddingVertical: theme.spacing[4], }, errorText: { color: theme.colors.palette.red[500], fontSize: theme.fontSize.sm, }, warningText: { color: theme.colors.palette.orange[500], fontSize: theme.fontSize.sm, }, helperText: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, }, selectorColumn: { flex: 1, gap: theme.spacing[3], }, selectorColumnFull: { width: "100%", }, toggleRow: { flexDirection: "row", alignItems: "center", gap: theme.spacing[3], paddingVertical: theme.spacing[2], }, toggleRowDisabled: { opacity: theme.opacity[50], }, checkbox: { width: 22, height: 22, borderRadius: theme.borderRadius.sm, borderWidth: theme.borderWidth[2], borderColor: theme.colors.border, alignItems: "center", justifyContent: "center", }, checkboxChecked: { borderColor: theme.colors.palette.blue[500], backgroundColor: theme.colors.palette.blue[500], }, checkboxDisabled: { borderColor: theme.colors.border, }, checkboxDot: { width: 10, height: 10, borderRadius: theme.borderRadius.full, backgroundColor: theme.colors.palette.white, }, toggleTextContainer: { flex: 1, gap: theme.spacing[1], }, toggleLabel: { color: theme.colors.foreground, fontSize: theme.fontSize.base, fontWeight: theme.fontWeight.semibold, }, input: { backgroundColor: theme.colors.surface0, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, borderRadius: theme.borderRadius.lg, paddingVertical: theme.spacing[3], paddingHorizontal: theme.spacing[4], color: theme.colors.foreground, fontSize: theme.fontSize.base, }, dropdownLoading: { flexDirection: "row", alignItems: "center", gap: theme.spacing[2], }, selectFieldContainer: { gap: theme.spacing[2], }, selectFieldControl: { flexDirection: "row", alignItems: "center", backgroundColor: theme.colors.surface0, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, borderRadius: theme.borderRadius.lg, paddingVertical: theme.spacing[3], paddingHorizontal: theme.spacing[4], }, selectFieldControlDisabled: { opacity: theme.opacity[50], }, selectFieldContent: { flex: 1, gap: theme.spacing[1], }, selectFieldLabel: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.xs, fontWeight: theme.fontWeight.medium, textTransform: "uppercase", letterSpacing: 0.5, }, selectFieldValue: { color: theme.colors.foreground, fontSize: theme.fontSize.base, }, selectFieldPlaceholder: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.base, }, gitOptionsContainer: { gap: theme.spacing[3], }, worktreeToggle: { flexDirection: "row", alignItems: "center", gap: theme.spacing[3], backgroundColor: theme.colors.surface0, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, borderRadius: theme.borderRadius.lg, paddingVertical: theme.spacing[3], paddingHorizontal: theme.spacing[4], }, worktreeToggleDisabled: { opacity: theme.opacity[50], }, worktreeToggleContent: { flex: 1, gap: theme.spacing[1], }, worktreeToggleLabel: { color: theme.colors.foreground, fontSize: theme.fontSize.base, fontWeight: theme.fontWeight.semibold, }, worktreeToggleDescription: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, }, baseBranchRow: { flexDirection: "row", alignItems: "center", gap: theme.spacing[2], paddingHorizontal: theme.spacing[4], }, baseBranchLabel: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, }, baseBranchValueRow: { flexDirection: "row", alignItems: "center", gap: theme.spacing[2], }, baseBranchValue: { color: theme.colors.foreground, fontSize: theme.fontSize.sm, fontWeight: theme.fontWeight.medium, }, baseBranchEditRow: { flex: 1, flexDirection: "row", alignItems: "center", gap: theme.spacing[2], }, baseBranchInput: { flex: 1, backgroundColor: theme.colors.surface0, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, borderRadius: theme.borderRadius.md, paddingVertical: theme.spacing[1], paddingHorizontal: theme.spacing[2], color: theme.colors.foreground, fontSize: theme.fontSize.sm, }, baseBranchIconButton: { padding: theme.spacing[1], }, desktopDropdownOverlay: { flex: 1, }, desktopDropdownBackdrop: { position: "absolute", top: 0, right: 0, bottom: 0, left: 0, }, desktopDropdownContainer: { backgroundColor: theme.colors.surface2, borderRadius: theme.borderRadius.lg, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, shadowColor: "#000", shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 12, elevation: 8, maxHeight: 400, }, desktopDropdownScroll: { maxHeight: 400, }, desktopDropdownScrollContent: { padding: theme.spacing[2], }, agentConfigRow: { flexDirection: "row", gap: theme.spacing[2], }, agentConfigColumn: { flex: 1, }, compactSelectControl: { backgroundColor: theme.colors.surface0, borderWidth: theme.borderWidth[1], borderColor: theme.colors.border, borderRadius: theme.borderRadius.lg, paddingVertical: theme.spacing[2], paddingHorizontal: theme.spacing[3], gap: theme.spacing[1], }, compactSelectControlDisabled: { opacity: theme.opacity[50], }, compactSelectLabel: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.xs, fontWeight: theme.fontWeight.medium, textTransform: "uppercase", letterSpacing: 0.5, }, compactSelectValue: { color: theme.colors.foreground, fontSize: theme.fontSize.sm, }, compactSelectPlaceholder: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, }, }));