Optimize custom endpoint management logic to distinguish between edit and create modes:
- Edit mode: endpoints are read/written directly to backend via API
- Create mode: use draftCustomEndpoints to stage, save on submit
- Remove duplicate endpoint loading in useSpeedTestEndpoints
- Add isSaving state and initialCustomUrls tracking
Implement Solution A (complete deferred submission) for custom endpoint
management, replacing the dual-mode system with unified local staging.
Changes:
- Remove immediate backend saves from EndpointSpeedTest
* handleAddEndpoint: local state update only
* handleRemoveEndpoint: local state update only
* handleSelect: remove lastUsed timestamp update
- Add explicit clear detection in ProviderForm
* Distinguish "user cleared endpoints" from "user didn't modify"
* Pass empty object {} as clear signal vs null for no-change
- Fix mergeProviderMeta to handle three distinct cases:
* null/undefined: don't modify endpoints (no meta sent)
* empty object {}: explicitly clear endpoints (send empty meta)
* with data: add/update endpoints (overwrite)
Fixed Critical Bug:
When users deleted all custom endpoints, changes were not saved because:
- draftCustomEndpoints=[] resulted in customEndpointsToSave=null
- mergeProviderMeta(meta, null) returned undefined
- Backend interpreted missing meta as "don't modify", preserving old values
Solution:
Detect when user had endpoints and cleared them (hadEndpoints && length===0),
then pass empty object to mergeProviderMeta as explicit clear signal.
Architecture Improvements:
- Transaction atomicity: all fields submitted together on form save
- UX consistency: add/edit modes behave identically
- Cancel button: true rollback with no immediate saves
- Code simplification: removed ~40 lines of immediate save error handling
Testing:
- TypeScript type check: passed
- Rust backend tests: 10/10 passed
- Build: successful
Rename `AppType` to `AppId` across the entire frontend codebase to better
reflect its purpose as an application identifier rather than a type category.
This aligns frontend naming with backend command parameter conventions.
Changes:
- Rename type `AppType` to `AppId` in src/lib/api/types.ts
- Remove `AppType` export from src/lib/api/index.ts
- Update all component props from `appType` to `appId` (43 files)
- Update all variable names from `appType` to `appId`
- Synchronize documentation (CHANGELOG, refactoring plans)
- Update test files and MSW mocks
BREAKING CHANGE: `AppType` type is no longer exported. Use `AppId` instead.
All component props have been renamed from `appType` to `appId`.
- 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)
- 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
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 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.
- Remove unused useDarkMode hook (now using shadcn theme-provider)
- Clean up MCP components (remove redundant code)
- Add restart API to settings
- Minor type improvements
- 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.