Commit Graph

456 Commits

  • 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
  • chore: clean up TODO comments in ProviderForm
    - Remove obsolete TODO comments for Codex Base URL handling
    - Codex Base URL is already fully managed by useCodexConfigState hook
    - useBaseUrlState is now only used for Claude mode
    - Add clarifying comments about the architecture
  • fix: enable endpoint speed test by calling backend API
    - Import vscodeApi to access backend test_api_endpoints command
    - Replace empty results array with actual API call
    - Remove TODO comments for implemented API calls
    - Enable all endpoint management features:
      - Speed test with latency measurement
      - Load custom endpoints from backend
      - Add/remove custom endpoints
      - Update endpoint last used time
    - Fix issue where clicking test button immediately showed failure
  • feat: add useSpeedTestEndpoints hook to collect all endpoint candidates for speed test modal
    - Create useSpeedTestEndpoints hook that collects endpoints from:
      1. Current baseUrl/codexBaseUrl
      2. Initial data URL (edit mode)
      3. Preset's endpointCandidates array
    - Pass speedTestEndpoints to ClaudeFormFields and CodexFormFields
    - Update EndpointSpeedTest to use collected endpoints instead of just current URL
    - Fix PackyCode preset endpoints not appearing in speed test modal
  • fix: enable base URL and endpoint editing for Codex providers in edit mode
    Fixed critical bug where CodexFormFields component was not rendered
    in edit mode, preventing users from:
    - Viewing and editing API base URL for custom/third-party Codex providers
    - Accessing endpoint speed test modal in edit mode
    - Updating API keys in edit mode
    
    Changed line 477 from:
      {appType === "codex" && !isEditMode && (
    To:
      {appType === "codex" && (
    
    This aligns Codex behavior with Claude, where all form fields are
    available in both create and edit modes for custom/third-party providers.
  • fix: allow API Key editing in edit mode
    Fixed logic in useApiKeyState.ts to correctly show API Key input
    when editing existing providers. Changed condition from
    `!isEditMode && hasApiKeyField(config)` to
    `isEditMode && hasApiKeyField(config)` to match the original
    form's behavior.
    
    This restores the ability to directly update API keys when
    editing existing providers that have API key fields in their
    configuration.
  • refactor: split ProviderForm into smaller focused components
    - Created ProviderPresetSelector component (80 lines)
    - Created BasicFormFields component (60 lines)
    - Created ClaudeFormFields component (272 lines)
    - Created CodexFormFields component (131 lines)
    - Reduced ProviderForm from 866 to 544 lines (37% reduction)
    
    Each component now has a clear single responsibility:
    - ProviderPresetSelector: Handles preset selection UI
    - BasicFormFields: Name and website URL inputs
    - ClaudeFormFields: All Claude-specific form fields
    - CodexFormFields: All Codex-specific form fields
    - ProviderForm: Orchestrates hooks and component composition
    
    Benefits:
    - Better code organization and maintainability
    - Easier to test individual components
    - Clearer separation of concerns
    - More reusable components
  • feat: integrate Codex common config snippet and template modal features
    - Created useCodexCommonConfig hook for managing Codex TOML common config
    - Persists to localStorage with key 'cc-switch:codex-common-config-snippet'
    - Added isCodexTemplateModalOpen state to ProviderForm
    - Connected all CodexConfigEditor props:
      - Common config snippet management (useCommonConfig, handlers)
      - Template modal state (isTemplateModalOpen, setIsTemplateModalOpen)
      - Form field callbacks (onWebsiteUrlChange, onNameChange)
      - Custom mode detection (isCustomMode)
    - Hook structure mirrors useCommonConfigSnippet for consistency
  • feat: add Claude common config snippet functionality
    - Create useCommonConfigSnippet hook to manage common config state
    - Create CommonConfigEditor component with modal for editing
    - Support merging/removing common config snippets from provider configs
    - Persist common config to localStorage for reuse across providers
    - Auto-detect if provider config contains common snippet
    - Replace JSON editor with CommonConfigEditor in ProviderForm
  • feat: implement template variables input functionality
    - Create useTemplateValues hook to manage template variable state
    - Support dynamic placeholder replacement in provider configs
    - Add template parameter input UI in provider form
    - Validate required template values before submission
    - Auto-update config when template values change
  • refactor: extract Kimi model selector logic to dedicated hook
    - Create useKimiModelSelector hook to manage Kimi-specific state
    - Auto-detect Kimi providers by preset name or config content
    - Support model initialization from existing config in edit mode
    - Sync model selections with JSON configuration
    - Maintain clean separation between UI and business logic
  • refactor: extract API Key link and custom endpoints logic into hooks
    - Create useApiKeyLink hook to manage API Key retrieval link display and URL
    - Create useCustomEndpoints hook to collect endpoints from multiple sources
    - Simplify ProviderForm by using these new hooks
    - Reduce code duplication and improve maintainability
    - Fix TypeScript error with form.watch("websiteUrl") by providing default empty string
  • feat: implement custom endpoint management
    - Add draftCustomEndpoints state to collect custom endpoints from speed test modal
    - Import CustomEndpoint type from @/types
    - Update handleSubmit to collect and package endpoints into meta.custom_endpoints:
      * User-added custom endpoints (from draftCustomEndpoints)
      * Preset endpointCandidates (if any)
      * Current Base URL (baseUrl/codexBaseUrl)
    - Add onCustomEndpointsChange callback to both Claude and Codex EndpointSpeedTest instances
    - Extend ProviderFormValues type to include meta.custom_endpoints field
    - Only creates meta.custom_endpoints for new providers (not edit mode)
    - Deduplicates URLs and creates CustomEndpoint entries with addedAt timestamp
  • feat: add API Key retrieval links for both Claude and Codex providers
    - Add shouldShowClaudeApiKeyLink logic based on provider category
    - Add shouldShowCodexApiKeyLink logic for Codex providers
    - Add getCurrentClaudeWebsiteUrl() to get website URL with apiKeyUrl priority for third-party providers
    - Add getCurrentCodexWebsiteUrl() with same logic for Codex
    - Add link UI below API Key input for both Claude and Codex
    - Links only show for cn_official, aggregator, and third_party categories
    - Preserve original UI styling with -mt-1 pl-1 positioning
  • feat: add Codex support to ProviderForm
    - Create useCodexConfigState hook for managing Codex configuration
      - Handles auth.json (JSON) and config.toml (TOML) separately
      - Bidirectional sync with Base URL extraction
      - API Key management from auth.OPENAI_API_KEY
    - Integrate Codex-specific UI components
      - Codex API Key input
      - Codex Base URL input with endpoint speed test
      - CodexConfigEditor for auth/config editing
    - Update handlePresetChange to support Codex presets
    - Update handleSubmit to compose Codex auth+config
    - Conditional rendering: Claude uses JsonEditor, Codex uses CodexConfigEditor
  • feat: add model selector to ProviderForm
    - Integrate useModelState hook for managing ANTHROPIC_MODEL and ANTHROPIC_SMALL_FAST_MODEL
    - Add two model input fields in responsive grid layout
    - Only show for non-official Claude providers
    - Include helper text explaining optional nature
    - Bidirectional sync between inputs and JSON config
  • feat: add Base URL input and endpoint speed test to ProviderForm
    - Integrate useBaseUrlState hook for managing Base URL
    - Add Base URL input field for third-party and custom providers
    - Add endpoint speed test modal with management button
    - Show Base URL section only for non-official providers
    - Add Zap icon button to open endpoint speed test modal
    - Pass baseUrl to EndpointSpeedTest component
    - Add helper text explaining API endpoint usage
    
    All TypeScript type checks pass.
  • refactor: create modular hooks and integrate API key input
    - Create custom hooks for state management:
      - useProviderCategory: manages provider category state
      - useApiKeyState: manages API key input with auto-sync to config
      - useBaseUrlState: manages base URL for Claude and Codex
      - useModelState: manages model selection state
    
    - Integrate API key input into simplified ProviderForm:
      - Add ApiKeyInput component for Claude mode
      - Auto-populate API key into settings config
      - Disable for official providers
    
    - Fix EndpointSpeedTest type errors:
      - Fix import paths to use @ alias
      - Add temporary type definitions
      - Format all TODO comments properly
      - Remove incorrect type assertions
      - Comment out unimplemented window.api checks
    
    All TypeScript type checks now pass.
  • refactor: convert provider preset selector to flat button layout
    Replace dropdown select menu with flat button layout matching MCP design.
    Selecting a preset now fills the form without auto-submitting.
  • fix: add scrollbars to provider dialogs and simplify theme toggle
    ## Changes
    
    ### Add scrollbars to provider dialogs
    - **AddProviderDialog.tsx**: Add max-h-[90vh], flex flex-col layout, and scrollable content wrapper
    - **EditProviderDialog.tsx**: Add max-h-[90vh], flex flex-col layout, and scrollable content wrapper
    - Both dialogs now follow the same scrolling pattern as other dialogs in the app
    - Wrap ProviderForm in `<div className="flex-1 overflow-y-auto -mx-6 px-6">` for proper scrolling
    
    ### Simplify theme toggle
    - **mode-toggle.tsx**: Change from dropdown menu to direct toggle button
    - Remove DropdownMenu and related imports
    - Click now directly toggles between light and dark mode
    - Simpler UX: one click to switch themes instead of opening a menu
    - Remove "system" theme option from quick toggle (still available in settings if needed)
    
    ## Benefits
    - **Consistent scrolling**: All dialogs now have proper scroll behavior when content exceeds viewport height
    - **Better UX**: Theme toggle is faster and more intuitive with direct click
    - **Code simplification**: Removed unnecessary dropdown menu complexity from theme toggle
    
    All TypeScript type checks and Prettier formatting checks pass.