import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { ReactElement, ReactNode } from "react"; import { View, Text, Pressable, TextInput, ActivityIndicator } from "react-native"; import type { StyleProp, ViewStyle, TextProps } from "react-native"; import { StyleSheet, useUnistyles } from "react-native-unistyles"; import { BottomSheetScrollView, BottomSheetBackdrop, BottomSheetBackgroundProps, } from "@gorhom/bottom-sheet"; import Animated from "react-native-reanimated"; import { ChevronDown, ChevronRight, Pencil, Check, X, Bot, Brain, ShieldCheck, ShieldAlert, ShieldOff, } from "lucide-react-native"; import type { AgentMode, AgentModelDefinition, AgentProvider, } from "@server/server/agent/agent-sdk-types"; import type { AgentProviderDefinition } from "@server/server/agent/provider-manifest"; import { getModeVisuals, type AgentModeIcon } from "@server/server/agent/provider-manifest"; import { Combobox, ComboboxItem } from "@/components/ui/combobox"; import { IsolatedBottomSheetModal, useIsolatedBottomSheetVisibility, } from "@/components/ui/isolated-bottom-sheet-modal"; import { baseColors } from "@/styles/theme"; import { isNative } from "@/constants/platform"; const MODE_ICON_MAP: Record = { ShieldCheck, ShieldAlert, ShieldOff, }; const MODE_COLOR_MAP: Record = { default: baseColors.blue[500], safe: baseColors.green[500], moderate: baseColors.amber[500], dangerous: baseColors.red[500], readonly: baseColors.purple[500], }; 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; testID?: string; } export function DropdownField({ label, value, placeholder, onPress, disabled, errorMessage, warningMessage, helperText, renderTrigger, testID, }: DropdownFieldProps): ReactElement { const { theme } = useUnistyles(); 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; valueEllipsizeMode?: "head" | "middle" | "tail" | "clip"; testID?: string; } export function SelectField({ label, value, placeholder, onPress, disabled, errorMessage, warningMessage, helperText, controlRef, valueEllipsizeMode, testID, }: SelectFieldProps): ReactElement { const { theme } = useUnistyles(); const getWebKey = useCallback((event: unknown): string | null => { if (!event || typeof event !== "object") return null; const eventWithNative = event as { nativeEvent?: unknown; key?: unknown }; if (typeof eventWithNative.key === "string") return eventWithNative.key; const nativeEvent = eventWithNative.nativeEvent as { key?: unknown } | undefined; return typeof nativeEvent?.key === "string" ? nativeEvent.key : null; }, []); const preventWebDefault = useCallback((event: unknown) => { if (!event || typeof event !== "object") return; const candidate = event as { preventDefault?: unknown }; if (typeof candidate.preventDefault === "function") { candidate.preventDefault(); } }, []); const handleKeyDown = useCallback( (event: unknown) => { if (isNative) return; const key = getWebKey(event); if (key === "Enter" || key === " ") { preventWebDefault(event); onPress(); } }, [getWebKey, onPress, preventWebDefault], ); const normalizedValue = (value ?? "").trim(); const normalizedPlaceholder = (placeholder ?? "").trim(); const hasConcreteValue = normalizedValue.length > 0 && (normalizedPlaceholder.length === 0 || normalizedValue !== normalizedPlaceholder); const displayText = hasConcreteValue ? normalizedValue : normalizedPlaceholder || "Select..."; 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) { const { theme } = useUnistyles(); return ( ); } export function DropdownSheet({ title, visible, onClose, children, }: DropdownSheetProps): ReactElement { const { theme } = useUnistyles(); const titleColor = theme.colors.foreground; const snapPoints = useMemo(() => ["60%", "90%"], []); const { sheetRef, handleSheetChange } = useIsolatedBottomSheetVisibility({ visible, onClose, }); const handleClose = useCallback(() => { onClose(); }, [onClose]); const renderBackdrop = useCallback( (props: React.ComponentProps) => ( ), [], ); return ( {title} {children} ); } // Re-export ComboboxItem as SelectOption for backwards compatibility const SelectOption = ComboboxItem; 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; icon?: ReactElement; showLabel?: boolean; testID?: string; } export function ComboSelect({ label, title, value, options, placeholder, disabled, allowCustomValue = false, isLoading, onSelect, icon, showLabel = true, testID, }: ComboSelectProps): ReactElement { const [isOpen, setIsOpen] = useState(false); const anchorRef = useRef(null); const selectedOption = options.find((opt) => opt.id === value); const displayValue = selectedOption?.label ?? ""; const isEmpty = options.length === 0; const handleOpen = useCallback(() => setIsOpen(true), []); const handleOpenChange = useCallback((open: boolean) => setIsOpen(open), []); return ( <> ); } interface CompactSelectFieldProps { label: string; value: string; placeholder?: string; onPress: () => void; disabled?: boolean; isLoading?: boolean; controlRef?: React.RefObject; icon?: ReactElement; showLabel?: boolean; containerStyle?: StyleProp; valueEllipsizeMode?: TextProps["ellipsizeMode"]; testID?: string; } export function FormSelectTrigger({ label, value, placeholder, onPress, disabled, isLoading, controlRef, icon, showLabel = true, containerStyle, valueEllipsizeMode, testID, }: CompactSelectFieldProps): ReactElement { const { theme } = useUnistyles(); const getWebKey = useCallback((event: unknown): string | null => { if (!event || typeof event !== "object") return null; const eventWithNative = event as { nativeEvent?: unknown; key?: unknown }; if (typeof eventWithNative.key === "string") return eventWithNative.key; const nativeEvent = eventWithNative.nativeEvent as { key?: unknown } | undefined; return typeof nativeEvent?.key === "string" ? nativeEvent.key : null; }, []); const preventWebDefault = useCallback((event: unknown) => { if (!event || typeof event !== "object") return; const candidate = event as { preventDefault?: unknown }; if (typeof candidate.preventDefault === "function") { candidate.preventDefault(); } }, []); const handleKeyDown = useCallback( (event: unknown) => { if (isNative) return; const key = getWebKey(event); if (key === "Enter" || key === " ") { preventWebDefault(event); onPress(); } }, [getWebKey, onPress, preventWebDefault], ); const normalizedValue = (value ?? "").trim(); const normalizedPlaceholder = (placeholder ?? "").trim(); const hasConcreteValue = normalizedValue.length > 0 && (normalizedPlaceholder.length === 0 || normalizedValue !== normalizedPlaceholder); const displayText = hasConcreteValue ? normalizedValue : normalizedPlaceholder || "Select..."; return ( {icon ? {icon} : null} {showLabel ? {label} : null} {isLoading ? ( ) : ( {displayText} )} ); } 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; thinkingOptions: NonNullable; selectedThinkingOptionId: string; onSelectThinkingOption: (thinkingOptionId: string) => void; disabled?: boolean; } export function AgentConfigRow({ providerDefinitions, selectedProvider, onSelectProvider, modeOptions, selectedMode, onSelectMode, models, selectedModel, isModelLoading, onSelectModel, thinkingOptions, selectedThinkingOptionId, onSelectThinkingOption, disabled, }: AgentConfigRowProps): ReactElement { const { theme } = useUnistyles(); const providerOptions: ComboSelectOption[] = useMemo( () => providerDefinitions.map((def) => ({ id: def.id, label: def.label, })), [providerDefinitions], ); const modeSelectOptions: ComboSelectOption[] = useMemo(() => { if (modeOptions.length === 0) { return [{ id: "", label: "Default" }]; } return modeOptions.map((mode) => ({ id: mode.id, label: mode.label, })); }, [modeOptions]); const modelSelectOptions: ComboSelectOption[] = useMemo(() => { return models.map((model) => ({ id: model.id, label: model.label, })); }, [models]); const thinkingSelectOptions: ComboSelectOption[] = useMemo( () => thinkingOptions.map((option) => ({ id: option.id, label: option.label, })), [thinkingOptions], ); const effectiveSelectedMode = selectedMode || (modeOptions.length > 0 ? modeOptions[0]?.id : ""); const effectiveSelectedThinkingOption = selectedThinkingOptionId || thinkingSelectOptions[0]?.id || ""; const selectedModeVisuals = getModeVisuals( selectedProvider, effectiveSelectedMode, providerDefinitions, ); const ModeIcon = MODE_ICON_MAP[selectedModeVisuals?.icon ?? "ShieldCheck"]; const modeIconColor = MODE_COLOR_MAP[selectedModeVisuals?.colorTier ?? "safe"]; return ( 0 ? "Select..." : "No providers available"} disabled={disabled || providerOptions.length === 0} onSelect={onSelectProvider} icon={} showLabel={false} testID="draft-provider-select" /> } showLabel={false} testID="draft-model-select" /> } showLabel={false} testID="draft-mode-select" /> {thinkingSelectOptions.length > 0 ? ( } showLabel={false} /> ) : null} ); } 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 options = useMemo( () => providerDefinitions.map((def) => ({ id: def.id, label: def.label, })), [providerDefinitions], ); const handleOpen = useCallback(() => setIsOpen(true), []); const handleOpenChange = useCallback((open: boolean) => setIsOpen(open), []); return ( <> onSelect(id as AgentProvider)} title="Choose assistant" open={isOpen} onOpenChange={handleOpenChange} anchorRef={anchorRef} /> ); } 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 options = useMemo( () => modeOptions.map((mode) => ({ id: mode.id, label: mode.label, description: mode.description, })), [modeOptions], ); const handleOpen = useCallback(() => { if (hasOptions) { setIsOpen(true); } }, [hasOptions]); const handleOpenChange = useCallback((open: boolean) => setIsOpen(open), []); return ( <> {hasOptions ? ( ) : 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 = models.find((model) => model.id === selectedModel)?.label ?? selectedModel ?? "Select model"; const placeholder = isLoading && models.length === 0 ? "Loading..." : "Select model"; const helperText = error ? undefined : isLoading ? "Fetching available models..." : models.length === 0 ? "This assistant did not expose selectable models." : undefined; const options = useMemo(() => { return models.map((model) => ({ id: model.id, label: model.label, description: model.description, })); }, [models]); const handleOpen = useCallback(() => setIsOpen(true), []); const handleOpenChange = useCallback((open: boolean) => setIsOpen(open), []); const handleSelect = useCallback( (id: string) => { onSelect(id); }, [onSelect], ); return ( <> ); } 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 options = useMemo( () => suggestedPaths.map((path) => ({ id: path, label: path })), [suggestedPaths], ); const handleOpen = useCallback(() => setIsOpen(true), []); const handleOpenChange = useCallback((open: boolean) => setIsOpen(open), []); const emptyText = "No agent directories match your search."; return ( <> ); } 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 { worktreeMode: "none" | "create" | "attach"; onWorktreeModeChange: (value: "none" | "create" | "attach") => void; worktreeSlug: string; currentBranch: string | null; baseBranch: string; onBaseBranchChange: (value: string) => void; status: "idle" | "loading" | "ready" | "error"; repoError: string | null; gitValidationError: string | null; baseBranchError: string | null; worktreeOptions: Array<{ path: string; label: string }>; selectedWorktreePath: string; worktreeOptionsStatus: "idle" | "loading" | "ready" | "error"; worktreeOptionsError: string | null; attachWorktreeError: string | null; onSelectWorktreePath: (path: string) => void; } export function GitOptionsSection({ worktreeMode, onWorktreeModeChange, worktreeSlug, currentBranch, baseBranch, onBaseBranchChange, status, repoError, gitValidationError, baseBranchError, worktreeOptions, selectedWorktreePath, worktreeOptionsStatus, worktreeOptionsError, attachWorktreeError, onSelectWorktreePath, }: GitOptionsSectionProps): ReactElement { const { theme } = useUnistyles(); const isLoading = status === "loading"; const isCreateMode = worktreeMode === "create"; const isAttachMode = worktreeMode === "attach"; const [isEditingBranch, setIsEditingBranch] = useState(false); const [editedBranch, setEditedBranch] = useState(baseBranch); const inputRef = useRef(null); const [isWorktreeSheetOpen, setIsWorktreeSheetOpen] = useState(false); 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"; const selectedWorktreeLabel = worktreeOptions.find((option) => option.path === selectedWorktreePath)?.label ?? ""; const worktreeHelperText = worktreeOptionsStatus === "loading" ? "Loading worktrees..." : worktreeOptions.length === 0 ? "No worktrees found" : null; return ( onWorktreeModeChange(isCreateMode ? "none" : "create")} disabled={isLoading} style={[styles.worktreeToggle, isLoading && styles.worktreeToggleDisabled]} > {isCreateMode ? : null} Create worktree {isLoading ? "Inspecting repository…" : isCreateMode ? `Will create: ${worktreeSlug || "preparing…"}` : currentBranch ? `Run isolated from ${currentBranch}` : "Run in an isolated directory"} onWorktreeModeChange(isAttachMode ? "none" : "attach")} disabled={isLoading} style={[styles.worktreeToggle, isLoading && styles.worktreeToggleDisabled]} > {isAttachMode ? : null} Attach to existing worktree {isLoading ? "Inspecting repository…" : "Pick a Paseo worktree by branch"} {isAttachMode ? ( <> setIsWorktreeSheetOpen(true)} disabled={isLoading || worktreeOptionsStatus === "loading"} helperText={worktreeHelperText} errorMessage={attachWorktreeError || worktreeOptionsError} testID="worktree-attach-picker" /> setIsWorktreeSheetOpen(false)} > {worktreeOptions.map((option, index) => ( { onSelectWorktreePath(option.path); setIsWorktreeSheetOpen(false); }} /> ))} ) : null} {isCreateMode ? ( 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, }, bottomSheetHeader: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", 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, 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.surface0, borderRadius: theme.borderRadius.lg, borderWidth: 1, borderColor: theme.colors.borderAccent, ...theme.shadow.md, maxHeight: 400, overflow: "hidden", }, desktopDropdownScroll: { maxHeight: 400, }, desktopDropdownScrollContent: { paddingVertical: theme.spacing[1], }, agentConfigRow: { flexDirection: { xs: "column", md: "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[1], paddingHorizontal: theme.spacing[3], gap: theme.spacing[1], }, compactSelectControlInline: { minHeight: 40, flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: theme.spacing[1], }, compactSelectControlDisabled: { opacity: theme.opacity[50], }, compactSelectTopRow: { flexDirection: "row", alignItems: "center", gap: theme.spacing[1], }, compactSelectLeading: { alignItems: "center", justifyContent: "center", marginRight: theme.spacing[1], }, compactSelectValueContainer: { flex: 1, minWidth: 0, gap: theme.spacing[1], }, compactSelectLabel: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.sm, fontWeight: theme.fontWeight.medium, }, compactSelectValue: { color: theme.colors.foreground, fontSize: theme.fontSize.base, }, compactSelectPlaceholder: { color: theme.colors.foregroundMuted, fontSize: theme.fontSize.base, }, }));