Commit Graph

728 Commits

  • feat: add provider duplicate functionality in edit mode
    Add a duplicate button next to the drag handle in edit mode that allows users to quickly copy existing provider configurations.
    
    - Add Copy icon button in ProviderCard next to drag handle
    - Implement handleDuplicateProvider in App.tsx with deep cloning
    - Copy all provider settings (settingsConfig, websiteUrl, category, meta)
    - Auto-generate new ID and timestamp, omit sortIndex for natural sorting
    - Append " copy" to duplicated provider name
    - Add i18n support (zh: "复制", en: "Duplicate")
    - Wire onDuplicate callback through ProviderList to ProviderCard
    
    The duplicated provider will appear below the original provider in the list, sorted by creation time.
  • refactor: improve drag handle icon and interaction feedback
    Replace GripVertical icon with MoveVertical for clearer vertical drag semantics. Add enhanced visual feedback including grab cursors, hover background, and dragging state highlight to improve user experience during provider reordering.
  • refactor: improve endpoint management type safety and error handling
    - Unify EndpointCandidate type definition in types.ts
    - Remove all 'as any' type assertions in useSpeedTestEndpoints
    - Add cleanup function to prevent race conditions in async operations
    - Fix stale error messages persisting after successful deletion
    - Improve error handling for endpoint deletion (distinguish not-found vs network errors)
    - Extract timeout magic numbers to ENDPOINT_TIMEOUT_SECS constant
    - Clarify URL validation to explicitly allow only http/https
    - Fix ambiguous payload.meta assignment logic in ProviderForm
    - Add i18n for new error messages (removeFailed, updateLastUsedFailed)
  • feat: add AnyRouter presets and update endpoints
    - Add AnyRouter provider presets for Claude and Codex with endpoint candidates and base_url
    - Simplify PackyCode endpoint candidates to primary domain + SLB for both Claude and Codex
    - Set default OPENAI_API_KEY to empty in Codex presets for safety (no placeholder key)
    - Update model placeholders to GLM-4.6 / GLM-4.5-Air in en/zh locales
  • refactor: remove required constraints and empty API key fields
    - Remove 'required' attribute from Codex auth.json textarea
    - Remove conditional 'required' logic from API key input field
    - Clean up Codex Official preset by removing null OPENAI_API_KEY entry
    - Allow more flexible form validation while maintaining backend checks
  • refactor: prevent apiKey field creation for official providers
    Improved useApiKeyState hook to explicitly handle category parameter:
    - Only create apiKey field for non-official providers in add mode
    - Explicitly check category !== undefined to avoid unintended behavior
    - Added comprehensive comments explaining the logic
    - Updated dependency array to include category parameter
    
    This ensures official provider configs remain clean without empty apiKey fields.
  • refactor: unify focus styles across all input fields
    Replace inconsistent focus border styles with a unified soft blue ring effect
    across all input and textarea components.
    
    Changes:
    - Add consistent focus:ring styles to Input and Textarea components
    - Use focus:ring-blue-500/20 (light) and focus:ring-blue-400/20 (dark)
    - Remove focus border color changes for a more subtle design
    - Update ApiKeyInput to match the unified focus style
    - Update all manual textarea elements (Codex and Claude configs)
    
    Benefits:
    - Consistent visual feedback across all form inputs
    - Soft, elegant focus indication with blue glow effect
    - No jarring border color changes
    - Better user experience with subtle, professional styling
    
    The focus effect now uses only a soft blue ring (20% opacity) without
    changing border colors, creating a more refined and less distracting
    interaction pattern.
  • chore: remove unused form components
    Remove two unused component files that have been superseded by other
    implementations:
    
    - ClaudeConfigEditor.tsx (162 lines): Replaced by CommonConfigEditor.tsx
    - PresetSelector.tsx (119 lines): Replaced by ProviderPresetSelector.tsx
    
    These components were never imported or used anywhere in the codebase.
    Total code reduction: 281 lines.
  • refactor: replace CodeMirror with plain textarea in config editors
    Replace JsonEditor (CodeMirror) with plain HTML textarea elements in Claude
    config editors to maintain consistency with Codex config editors and eliminate
    theme conflicts.
    
    Changes:
    - Replace JsonEditor with textarea in ClaudeConfigEditor.tsx
    - Replace JsonEditor with textarea in CommonConfigEditor.tsx
    - Remove unnecessary dark mode detection logic
    - Remove wrapper div with border class that caused double borders
    - Apply unified border design system (border-border-default)
    - Keep JsonEditor in UsageScriptModal for JavaScript code editing
    
    Benefits:
    - Eliminates CodeMirror theme conflicts with oneDark
    - Simplifies codebase by removing unnecessary abstractions
    - Consistent styling across all config input fields
    - Automatic theme adaptation via CSS variables
  • refactor: complete border unification across all components
    - Add border styles to JsonEditor (CodeMirror) with theme-responsive colors
    - Update all dialog header/footer dividers to use border-border-default
    - Replace remaining border-border instances in settings components
    - Ensure all borders (including separators and container borders) use unified design system
    - All borders now consistently use CSS variables and respond to light/dark themes
  • refactor: implement unified border design system
    - Define custom border utilities in @layer utilities for consistent theming
    - Add border-default (1px gray), border-active (2px primary), border-hover (40% primary), and border-dragging (60% primary) classes
    - Update all UI components (Input, Select, TextArea, Button, Dialog, Dropdown) to use unified border classes
    - Replace hardcoded border colors (gray-200/300/600/700) with theme-responsive border-border-default
    - Update provider cards, MCP components, settings, and forms with new border system
    - Remove dark mode border overrides to simplify CSS and improve maintainability
    - Ensure all borders automatically adapt to light/dark themes via CSS variables
  • refine: center toast notifications and silence plugin sync feedback
    - Change toast position from top-right to top-center for better visibility
    - Remove success notifications for plugin sync operations to reduce noise
    - Keep error notifications to alert users of actual issues
  • fix: eliminate layout shift when switching providers
    - Use opacity transition instead of conditional rendering for "current" badge to prevent height changes
    - Add min-h-[20px] to title row to maintain consistent height
    - Use 2px border for active provider, 1px for inactive to improve visual distinction
    - Remove global border-color rule that was overriding Tailwind utilities
    - Use HSL arbitrary values for border colors to work with Tailwind 4 + shadcn/ui
  • refine: improve UI consistency and spacing in header and provider cards
    - Reduce header spacing (gap-4 → gap-2, gap-1.5 → gap-1) for more compact layout
    - Unify provider link colors with main title (blue-500/blue-400)
    - Standardize action button styles to use size="icon" for consistent hover effects
    - Add proper hover backgrounds to provider action buttons matching header buttons
  • feat: add unique icons and colors for preset providers
    Add visual theme system for provider presets with custom icons and brand colors:
    
    - Add PresetTheme interface supporting icon type and custom colors
    - Claude Official: Claude brand icon + orange theme (#D97757)
    - Codex Official: Codex brand icon + dark gray theme (#1F2937)
    - Other presets: Default to theme blue (bg-blue-500)
    - Custom config: Uses theme blue for consistency
    
    Technical changes:
    - Extend ProviderPreset and CodexProviderPreset interfaces with optional theme field
    - Update ProviderPresetSelector to render icons and apply theme colors
    - Support both Tailwind classes and hex colors via inline styles
    - Remove unused Link import from ProviderCard
    
    This restores the unique visual identity for official providers while
    maintaining a unified theme color for third-party presets.
  • refine: improve visual feedback for in-use provider actions
    - Add subtle gray background to "In Use" button for better visual distinction
    - Enhance disabled state of delete button with opacity and cursor feedback
    - Remove disabled attribute to allow pointer events for better UX
    - Prevent delete action via conditional onClick instead of disabled prop
  • refine: animate drag handle with push effect in edit mode
    - Remove flex gap-3 from parent container to enable width animation
    - Add conditional width (w-8/w-0) and margin-right (mr-3/mr-0) to drag handle button
    - Add overflow-hidden to prevent icon overflow during width transition
    - Content now smoothly shifts right by 44px when entering edit mode
    - Maintains 200ms transition-all for smooth push animation
    
    This creates a more natural "push-out" effect where the drag handle
    appears to push the provider content aside, rather than just fading in.
  • feat: add edit mode toggle to show/hide drag handles
    - Add edit mode button next to settings in header
    - Edit button turns blue when active
    - Drag handles fade in/out with edit mode toggle
    - Add smooth 200ms transition animation
    - Add i18n support for edit mode (en/zh)
    - Maintain consistent spacing between header elements
  • refine: improve provider card UI with compact action buttons and simplified link styling
    - Convert edit and usage buttons to icon-only ghost variant for cleaner appearance
    - Reduce action button padding (px-2) and group spacing (gap-0) for more compact layout
    - Add red hover effect to delete icon for better visual feedback
    - Vertically center action buttons with provider info on desktop view
    - Simplify provider URL link by removing icon and using soft blue color (blue-400/300)
    - Reduce enable button width from 96px to 80px for better proportions
  • feat: add category-specific hints to provider form
    - Add dynamic hint text based on provider category (official, opensource, aggregator, third-party, custom)
    - Display hints in ProviderPresetSelector below preset buttons
    - Rename "Chinese official" to "Opensource official" for better clarity
    - Add i18n keys for all category hints in both zh and en locales
    - Remove redundant hint boxes from ClaudeFormFields and CodexFormFields
    
    This improves user guidance by showing contextual hints that explain
    what fields are required for each provider category.
  • refine: standardize provider dialog dimensions to match MCP panel
    Adjusted Add and Edit provider dialogs to use consistent sizing with MCP panel:
    - Increased max width from max-w-2xl to max-w-3xl
    - Unified max height to max-h-[85vh] (was 90vh)
    - Added min-h-[600px] for minimum height constraint
    
    This ensures visual consistency across all major dialog panels in the app.
  • i18n: complete internationalization for provider and usage query panels
    - Add 45+ new translation keys for usage query and usage script features
    - Fix duplicate provider object in translation files that caused missing translations
    - Remove all hardcoded Chinese text and defaultValue fallbacks from components
    - Add proper translations for:
      * Usage footer (query status, plan usage display)
      * Usage script modal (script editor, validation, test controls)
      * Provider forms (basic fields, endpoints, model selectors)
      * Provider dialogs (add/edit hints and titles)
    
    Modified 16 files:
    - 2 translation files (zh.json, en.json)
    - 14 component files (removed defaultValue, added t() calls)
    
    All UI text now properly supports Chinese/English switching.
  • i18n: complete internationalization for settings panel
    - Add missing translation keys for all hint texts and descriptions
    - Remove all hardcoded defaultValue parameters from components
    - Add translations for window behavior, directory settings, and theme settings
    - Add translations for provider-related UI elements
    - Improve consistency across Chinese and English translations
    
    Translation additions:
    - common.toggleTheme
    - settings.windowBehaviorHint, claudeConfigDirDescription, codexConfigDirDescription
    - provider.* (12 new keys)
    - providerForm.* (15 new keys)
    - providerPreset.* (4 new keys)
    
    Modified files: 10
    Lines changed: +132 -74
  • fix: standardize MCP panel button font sizes to match app-wide consistency
    Remove size="sm" from MCP panel buttons to use default text-sm instead of text-xs, ensuring visual consistency with buttons throughout the application.
  • fix: improve dialog vertical alignment and spacing consistency
    Fix multiple alignment and spacing issues in dialog components to ensure
    proper visual balance and symmetry across all dialog elements.
    
    Changes to DialogHeader:
    - Change padding from pt-6 pb-4 to py-5 for symmetric vertical spacing
    - Ensures header content is equidistant from top and bottom borders
    
    Changes to DialogFooter:
    - Change padding from pt-4 pb-6 to py-5 for symmetric vertical spacing
    - Replace sm:space-x-2 with gap-2 for consistent button spacing at all breakpoints
    - Add sm:items-center to vertically center buttons in horizontal layout
    - Ensures footer buttons align properly and are equidistant from borders
    
    Changes to DialogTitle:
    - Change line-height from leading-none to leading-tight (1 → 1.25)
    - Provides better visual balance with button heights
    - Improves readability and alignment with adjacent buttons
    
    Impact:
    All dialog components now have:
    - Symmetric vertical padding (1.25rem top/bottom)
    - Properly centered content regardless of viewport size
    - Consistent button spacing and alignment
    - Better visual harmony between text and interactive elements
  • refine: improve MCP panel spacing and add icon consistency
    Enhance visual consistency across MCP dialogs with better spacing
    and appropriate icons for add/edit actions.
    
    Changes:
    - McpFormModal: Use Plus icon for "Add" button, Save icon for "Edit" button
    - McpPanel: Balance spacing around server info line (py-4 for info section,
      pb-4 for content area) to create equal visual weight between header and
      server list
    
    The MCP panel now has consistent vertical rhythm with 1rem spacing above
    and below the server count info line.
  • feat: add icons to provider dialog action buttons
    Add visual indicators to the Add and Save buttons in provider dialogs
    for improved UX and consistency with other dialogs.
    
    Changes:
    - AddProviderDialog: Add Plus icon to "Add" button
    - EditProviderDialog: Add Save icon to "Save" button
    
    Both dialogs now have clear visual affordances for primary actions,
    matching the icon usage pattern in other modal dialogs throughout
    the application.
  • refactor: move provider form buttons to DialogFooter for consistency
    Restructure AddProviderDialog and EditProviderDialog to follow the
    standardized dialog layout pattern with buttons in DialogFooter.
    
    Changes:
    - Add DialogFooter to AddProviderDialog and EditProviderDialog
    - Add `showButtons` prop to ProviderForm (default: true for backward compatibility)
    - Add `id="provider-form"` to form element for external form submission
    - Move Cancel and Submit buttons from ProviderForm to DialogFooter
    - Use `form="provider-form"` attribute on DialogFooter buttons to trigger submission
    
    Benefits:
    - Consistent dialog footer appearance across all dialogs
    - Proper spacing and alignment with other modal dialogs
    - Better visual hierarchy with separated content and action areas
    - Maintains backward compatibility for ProviderForm usage elsewhere
    
    All provider dialogs now follow the unified pattern:
    - DialogHeader: Title and description
    - Content area: flex-1 overflow-y-auto px-6 py-4
    - DialogFooter: Action buttons with standard styling
  • refactor: standardize dialog components to use consistent DialogFooter styling
    Remove custom styling from DialogFooter components across the application
    to ensure consistent appearance and behavior. All dialogs now follow the
    unified layout pattern defined in the base Dialog component.
    
    Changes:
    - Remove custom className overrides from DialogFooter in:
      - EndpointSpeedTest.tsx
      - CodexQuickWizardModal.tsx
      - CodexCommonConfigModal.tsx
      - ClaudeConfigEditor.tsx
    - Fix McpWizardModal content area padding (remove -mx-6 negative margin)
    - Fix McpPanel to use DialogFooter component instead of custom div
    
    All dialogs now consistently use:
    - DialogHeader: px-6 pt-6 pb-4 with border and background (built-in)
    - Content area: flex-1 overflow-y-auto px-6 py-4
    - DialogFooter: px-6 pb-6 pt-4 with border and background (built-in)
    
    This ensures proper spacing, alignment, and visual consistency across
    all modal dialogs in the application.
  • fix: unify dialog layout and fix content padding issues
    - Fix negative margin overflow in all dialog content areas
    - Standardize dialog structure with flex-col layout
    - Add consistent py-4 spacing to all content areas
    - Ensure proper spacing between header, content, and footer
    
    Affected components:
    - AddProviderDialog, EditProviderDialog
    - McpFormModal, McpPanel
    - UsageScriptModal
    - SettingsDialog
    
    All dialogs now follow unified layout pattern:
    - DialogContent: flex flex-col max-h-[90vh]
    - Content area: flex-1 overflow-y-auto px-6 py-4
    - No negative margins that cause content overflow
  • fix: improve settings dialog UX with stable button width and smart scrollbar
    Fix two UX issues in the settings dialog:
    
    1. Check for Updates button width stability
       - Added min-w-[140px] to prevent layout shift during state changes
       - Button maintains consistent width across all states:
         * "Check for Updates" (idle)
         * "Checking..." (with spinner)
         * "Update to vX.X.X" (with download icon)
         * "Installing..." (with spinner)
    
    2. Settings dialog scrollbar behavior
       - Changed overflow-y-scroll to overflow-y-auto
       - Scrollbar now only appears when content actually overflows
       - Prevents unnecessary scrollbar on About tab (content < 400px)
       - Maintains min-h-[400px] on all tabs to prevent dialog height jump
    
    These changes improve visual stability and reduce UI clutter while
    maintaining consistent dialog dimensions during tab switching.
  • feat: move theme toggle to settings dialog
    Move the theme toggle from the main header to the settings dialog for a
    cleaner UI and better organization. The new theme selector uses a
    button group design consistent with the language settings.
    
    Changes:
    - Created ThemeSettings component with three options: Light, Dark, System
    - Added ThemeSettings to the General tab in settings dialog
    - Removed ModeToggle component from main header
    - Added theme-related i18n keys for all options
    - Theme selection takes effect immediately without requiring save
    
    Design:
    - Uses button group style matching LanguageSettings
    - Icons for each theme option (Sun, Moon, Monitor)
    - Consistent with app's blue theme for active state
    - Smooth transitions and hover effects
    
    This change simplifies the main header and consolidates all appearance
    settings in one place, improving the overall user experience.
  • refactor: remove config file location display feature
    Remove the config file location display from settings dialog to simplify
    the user interface. Users who need to access the config file can still do
    so through the advanced settings section.
    
    Changes:
    - Removed ConfigPathDisplay component and its usage
    - Removed configPath and openConfigFolder from useSettings hook
    - Removed configPath and openConfigFolder from useSettingsMetadata hook
    - Removed related i18n keys: configFileLocation, openFolder
    - Updated settings dialog to remove the config path display section
    
    This simplifies the settings UI while maintaining access to config
    directory management through the advanced settings tab.
  • refine: enhance settings dialog UI with improved visual feedback
    Improve the visual hierarchy and interaction feedback in the settings dialog:
    
    1. Tab navigation enhancement:
       - Active tabs now use blue background (blue-500/600) with white text
       - Add shadow effect to active tabs for better depth perception
       - Inactive tabs show hover effects (opacity + background)
       - Consistent with app's primary blue theme color
    
    2. Switch component visual improvement:
       - Checked state: blue background (blue-500/600) for clear indication
       - Unchecked state: gray background (gray-300/700) for neutral appearance
       - White thumb color for better contrast on both states
       - Enhanced focus ring (ring-2 + offset-2) for accessibility
    
    3. Layout spacing refinement:
       - Change content area padding from pb-4 to py-4 for symmetrical spacing
       - Ensure consistent 4-unit spacing between all dialog sections
    
    4. Clarify plugin integration description:
       - Update description to accurately reflect that provider switching
         in this app will sync with VS Code Claude Code extension
       - Previous wording was ambiguous about the synchronization behavior
    
    Files changed:
    - src/components/ui/tabs.tsx: Enhanced tab visual states
    - src/components/ui/switch.tsx: Improved switch contrast
    - src/components/settings/SettingsDialog.tsx: Fixed spacing
    - src/i18n/locales/{zh,en}.json: Updated plugin description
  • refine: improve settings dialog layout spacing and fix footer visibility
    This commit refines the visual hierarchy and fixes layout issues in the
    settings dialog:
    
    1. Add visual separators to dialog sections:
       - Add bottom border and background to DialogHeader
       - Both header and footer now have consistent border + bg-muted/20 styling
       - Creates clear three-section layout: header | content | footer
    
    2. Fix footer overflow issue:
       - Remove min-h-[480px] from content area that conflicted with max-h-[90vh]
       - Keep min-h-[400px] on TabsContent to prevent height jumps
       - Add flex-shrink-0 to header and footer to ensure they stay visible
       - Content area uses flex-1 to fill remaining space naturally
    
    3. Improve spacing:
       - Add pb-4 to content area for breathing room above footer
       - Add pb-4 to DialogHeader for consistent spacing below title
       - Ensure proper padding hierarchy across all dialog sections
    
    Layout calculation (small screens, 90vh ≈ 540px):
    - Header: ~70px (fixed)
    - Content: 400px minimum, scrollable (flexible)
    - Footer: ~70px (fixed)
    - Total: ≤ 540px, footer always visible ✓
    
    Files modified:
    - src/components/ui/dialog.tsx (DialogHeader, DialogFooter styling)
    - src/components/settings/SettingsDialog.tsx (content area height constraint)
  • fix: redesign settings dialog layout to prevent content overflow and visual jitter
    Fixed multiple layout issues in the settings dialog:
    
    1. Dialog structure: Changed from grid to flexbox layout
       - Removed global padding from DialogContent
       - Added individual padding to DialogHeader (px-6 pt-6) and DialogFooter (px-6 pb-6 pt-4)
       - Added max-h-[90vh] constraint to prevent dialog from exceeding viewport
    
    2. Content area improvements:
       - Replaced max-h-[70vh] with flex-1 for better space utilization
       - Set min-h-[480px] on content wrapper to maintain consistent dialog height
       - Applied min-h-[400px] to all TabsContent components to prevent height jumps
    
    3. Scrollbar optimization:
       - Changed overflow-y-auto to overflow-y-scroll to force scrollbar gutter
       - Eliminates horizontal shift when switching between tabs with different content heights
       - Consistent with main app layout approach (App.tsx)
    
    4. Footer enhancement:
       - Added border-t and bg-muted/20 for visual separation
       - Fixed footer overlapping content in advanced tab
    
    Result: Settings dialog now displays all content properly without requiring
    fullscreen, maintains consistent height across tabs, and eliminates layout shift
    when switching tabs.
  • fix: eliminate layout shift when switching between Claude and Codex
    Fixed dual-source jitter issue:
    1. Horizontal shift: Use overflow-y-scroll to force scrollbar gutter
    2. Vertical jump: Use keepPreviousData to maintain content during app switch
  • refactor: unify modal overlay system with shadcn/ui Dialog
    Fix inconsistent modal overlays by migrating all custom implementations
    to the unified shadcn/ui Dialog component with proper z-index layering.
    
    Changes:
    - Update Dialog component to support three z-index levels:
      - base (z-40): First-level dialogs
      - nested (z-50): Nested dialogs
      - alert (z-[60]): Alert/confirmation dialogs (using Tailwind arbitrary value)
    - Refactor all custom modal implementations to use Dialog:
      - EndpointSpeedTest: API endpoint speed testing panel
      - ClaudeConfigEditor: Claude common config editor
      - CodexQuickWizardModal: Codex quick setup wizard
      - CodexCommonConfigModal: Codex common config editor
      - SettingsDialog: Restart confirmation prompt
    - Remove custom backdrop implementations and manual z-index
    - Leverage Radix UI Portal for automatic DOM order management
    - Ensure consistent overlay behavior and keyboard interactions
    
    This eliminates the "background residue" issue where overlays from
    different layers would conflict, providing a unified and professional
    user experience across all modal interactions.
  • fix: prevent language setting rollback after successful save
    Introduce `closeAfterSave` callback to distinguish between save-and-close and cancel-and-close scenarios. Previously, saving settings would trigger `resetSettings()`, causing language changes to revert and requiring users to save twice for the change to take effect.
    
    Changes:
    - Add `closeAfterSave()`: close dialog without resetting settings after successful save
    - Keep `closeDialog()`: reset settings when canceling or directly closing dialog
    - Update save flow to use `closeAfterSave()` in `handleSaveClick`, `handleRestartLater`, and `handleRestartNow`
  • fix: prevent language switch state reset caused by dependency cycle
    Fixed an issue where clicking the language switcher would cause a brief flash
    and fail to persist the language change. The root cause was a dependency cycle
    in useSettingsForm where readPersistedLanguage depended on i18n.language,
    causing the initialization effect to re-run and reset state whenever the
    language changed.
    
    Changed the dependency from [i18n.language] to [i18n] since the i18n object
    itself is stable and doesn't change when the language changes, while the
    function can still access the current language value via closure.
  • refactor: unify EndpointSpeedTest with shadcn/ui components
    Replace native HTML elements with shadcn/ui components:
    - <button> → <Button> with variants (default, outline, ghost)
    - <input type="url"> → <Input> component
    
    Benefits:
    - Consistent styling across the application
    - Better accessibility and theming support
    - Reduced custom CSS classes
    - Type-safe component props
  • refactor: improve code quality and consistency
    Changes:
    1. Remove unused variable in useSettings.ts (readPersistedLanguage)
    2. Replace manual state management with React Query in UsageFooter
       - Create useUsageQuery hook with 5-minute cache
       - Simplify component from 227 lines to 81 lines (-64%)
       - Improve consistency with project's React Query pattern
       - Enable automatic refetch and error handling
  • refactor: split CodexConfigEditor into specialized components
    Before optimization:
    - CodexConfigEditor.tsx: 675 lines (monolithic component)
    
    After optimization:
    - CodexConfigEditor.tsx: 131 lines (-81%, orchestration only)
    - CodexQuickWizardModal.tsx: 325 lines (quick wizard modal)
    - CodexCommonConfigModal.tsx: 126 lines (common config modal)
    - CodexConfigSections.tsx: 150 lines (auth & config sections)
    - Total: 732 lines (+57 lines, but highly modular)
    
    Benefits:
     Single Responsibility: each component has one clear purpose
     Maintainability: reduced file size makes code easier to understand
     Reusability: modal components can be used independently
     Testability: isolated components are easier to test
     Readability: main component is now just orchestration logic
     Consistency: follows same modal patterns across app
    
    Component breakdown:
    - CodexConfigEditor: orchestration + state management (131 lines)
    - CodexQuickWizardModal: step-by-step wizard for quick config (325 lines)
    - CodexCommonConfigModal: common TOML configuration editor (126 lines)
    - CodexAuthSection: auth.json editor UI (70 lines)
    - CodexConfigSection: config.toml editor UI (80 lines)
  • refactor: extract MCP business logic to useMcpActions hook
    Before optimization:
    - McpPanel.tsx: 298 lines (component + business logic)
    
    After optimization:
    - McpPanel.tsx: 234 lines (-21%, UI focused)
    - useMcpActions.ts: 137 lines (business logic)
    
    Benefits:
     Separation of concerns: UI vs business logic
     Reusability: MCP operations can be used in other components
     Testability: business logic can be tested independently
     Consistency: follows same pattern as useProviderActions
     Optimistic updates: toggle enabled status with rollback on error
     Unified error handling: all MCP errors use toast notifications
    
    Technical details:
    - Extract reload, toggleEnabled, saveServer, deleteServer
    - Implement optimistic UI updates for toggle
    - Centralize error handling and toast messages
    - Remove duplicate error handling code from component
  • refactor: split useSettings hook into specialized hooks
    Before optimization:
    - useSettings.ts: 516 lines (single monolithic hook)
    
    After optimization:
    - useSettingsForm.ts: 158 lines (form state management)
    - useDirectorySettings.ts: 297 lines (directory management)
    - useSettingsMetadata.ts: 95 lines (metadata management)
    - useSettings.ts: 215 lines (composition layer)
    - Total: 765 lines (+249 lines, but with clear separation of concerns)
    
    Benefits:
     Single Responsibility Principle: each hook focuses on one domain
     Testability: independent hooks are easier to unit test
     Reusability: specialized hooks can be reused in other components
     Maintainability: reduced cognitive load per file
     Zero breaking changes: SettingsDialog auto-adapted to new interface
    
    Technical details:
    - useSettingsForm: pure form state + language sync
    - useDirectorySettings: directory selection/reset + default value computation
    - useSettingsMetadata: config path + portable mode + restart flag
    - useSettings: composition layer + save logic + reset logic
  • refactor: extract business logic to useProviderActions hook
    Major improvements:
    - Create `src/hooks/useProviderActions.ts` (147 lines)
      - Consolidate provider operations (add, update, delete, switch)
      - Extract Claude plugin sync logic
      - Extract usage script save logic
    
    - Simplify `App.tsx` (347 → 226 lines, -35%)
      - Remove 8 callback functions
      - Remove Claude plugin sync logic
      - Remove usage script save logic
      - Cleaner and more maintainable
    
    - Replace `onNotify` prop with `toast` in:
      - `UsageScriptModal.tsx`
      - `McpPanel.tsx`
      - `McpFormModal.tsx`
      - `McpWizardModal.tsx`
      - Unified notification system using sonner
    
    Benefits:
    - Reduced coupling and improved maintainability
    - Business logic isolated in hooks, easier to test
    - Consistent notification system across the app
  • refactor: cleanup and minor improvements
    - Remove unused useDarkMode hook (now using shadcn theme-provider)
    - Clean up MCP components (remove redundant code)
    - Add restart API to settings
    - Minor type improvements
  • refactor: extract validation logic into useMcpValidation hook
    Extract all MCP form validation logic into a reusable custom hook to
    improve code organization and enable reuse across components.
    
    Changes:
    - Create useMcpValidation hook with 4 validation functions:
      * validateJson: basic JSON structure validation
      * formatTomlError: unified TOML error formatting with i18n
      * validateTomlConfig: complete TOML validation with required fields
      * validateJsonConfig: complete JSON validation with structure checks
    
    - Update McpFormModal to use the hook instead of inline validation
    - Simplify validation calls throughout the component
    - Reduce code duplication while maintaining all functionality
    
    Benefits:
    - Validation logic can be reused in other MCP-related components
    - Easier to test validation in isolation
    - Better separation of concerns
    - McpFormModal remains at 699 lines (original: 767), kept cohesive
    
    The component stays as one piece since its 700 lines represent a
    single, cohesive form feature rather than multiple unrelated concerns.
  • refactor: unify directory structure and extract shared components
    - Migrate all form components from ProviderForm/ to providers/forms/
    - Create shared components to eliminate code duplication:
      * ApiKeySection: unified API key input with "Get API Key" link
      * EndpointField: unified endpoint URL input with manage button
    - Refactor ClaudeFormFields (-31% lines) and CodexFormFields (-33% lines)
    - Update all import paths to use new locations
    - Reduce code duplication from ~12% to ~7%
    
    This change improves maintainability and makes the codebase more DRY.
  • feat: add real-time TOML validation for Codex config
    - Add smol-toml dependency for client-side TOML parsing
    - Create useCodexTomlValidation hook with 500ms debounce
    - Display validation errors below config.toml textarea
    - Trigger validation on onChange for immediate user feedback
    - Backend validation remains as fallback for data integrity