Commit Graph
16 Commits
Author SHA1 Message Date
YoVinchen 0ef8c127c5 fix(common-config): improve error handling, layer separation, and reliability across sync system
P0 Fixes:
- Enable toml `preserve_order` feature for reliable key ordering
- Extract pure detection functions to utils/commonConfigDetection.ts (fix layer inversion)
- Return structured result from preserveCodexConfigFormat to prevent data loss

P1 Fixes:
- Handle pure TOML strings in Codex config instead of silent skip
- Surface extractDiff errors in useCodexCommonConfig instead of swallowing
- Log parse errors in detectCommonConfigEnabledByContent for debugging

P2 Fixes:
- Use parsing-based assertions in Rust TOML ordering tests
- Add schema warning when Codex config field is wrong type
- Add depth/node limits to isSubset function (prevent stack overflow)
- Replace hardcoded "{}" check with adapter.hasValidContent()

P3 Fixes:
- Refactor Gemini errors to structured GeminiConfigErrorInfo format
- Add mapGeminiErrorToI18n for type-safe error-to-i18n mapping
2026-01-31 20:39:28 +08:00
YoVinchen d66f196378 refactor(common-config): consolidate hasContent methods into adapters
- Add hasContent method to CommonConfigAdapter interface
- Move isSubset utility to configMerge.ts for reuse
- Export preserveCodexConfigFormat from adapters for hook use
- Add hasContentByAppType dispatcher for unified content detection
- Remove dead code from providerConfigUtils (hasCommonConfigSnippet,
  hasTomlCommonConfigSnippet, hasGeminiCommonConfigSnippet)
2026-01-31 15:23:49 +08:00
YoVinchen aa1231903f refactor(common-config): consolidate hooks and migrate Gemini to ENV format
- Delete redundant wrapper hooks (useCommonConfigSnippet, useGeminiCommonConfig)
- Change Gemini common config from JSON to ENV format (.env style)
- Add backend validation with forbidden keys filtering (GEMINI_API_KEY, GOOGLE_GEMINI_BASE_URL)
- Fix localStorage migration to skip empty parsed snippets
- Add error handling for silent JSON parse failures
- Clean up debug logs and unused types
2026-01-30 10:16:57 +08:00
YoVinchen 3b61fab4b5 refactor: unify common config hooks with generic base hook and adapters
- Create useCommonConfigBase generic hook (~300 lines)
- Create commonConfigAdapters for Claude (JSON), Codex (TOML), Gemini (ENV/JSON)
- Refactor three hooks from ~1370 lines to ~430 lines (-940 lines)
- Extract useDarkMode hook from three ConfigSections components
- Remove dead code: backend _str functions, frontend JSON/TOML unused exports
- Deduplicate deepClone/deepMerge utilities
- Fix duplicate mod tests in provider.rs
2026-01-29 22:35:52 +08:00
YoVinchen 982f78af0f fix(codex): fix config.toml not updated after extracting common config
The handleExtract function assumed codexConfig was JSON format, but it's
actually a pure TOML string from useCodexConfigState. JSON.parse() failed
silently, causing onConfigChange not to be called.

Changes:
- Handle both pure TOML string and legacy JSON format
- Add missing i18n key for zh.json
2026-01-29 18:38:02 +08:00
YoVinchen 3f68f78331 fix(config): defer common config save until form submission
- Change handleExtract and handleCommonConfigSnippetChange to use delayed save pattern
- Add hasUnsavedCommonConfig state to track pending changes
- Add getPendingCommonConfigSnippet and markCommonConfigSaved helper functions
- Remove immediate backend API calls, save only on form submit
- Add extractSuccessNeedSave and saveCommonConfigFailed i18n keys
2026-01-29 00:54:48 +08:00
YoVinchen 0ecf6891c0 refactor(hooks): improve error handling and user feedback
Address code audit findings #3, #5, #9:

Save queue improvements:
- Add error logging in enqueueSave() catch handlers
- Use console.error with [SaveQueue] prefix for debugging
- Prevent silent failures in async save operations

Extract operation improvements:
- Add toast.success() notification after extract completes
- Notify user that custom config was automatically updated
- Add error logging for failed settingsConfig updates

I18n improvements:
- Replace MCP i18n keys with dedicated Codex keys:
  - codexConfig.tomlFormatError
  - codexConfig.tomlSyntaxError
  - codexConfig.extractedTomlInvalid
- Avoid namespace pollution between modules
2026-01-26 15:55:40 +08:00
YoVinchen 2ff329f6c0 refactor(hooks): redesign common config hooks for runtime merge architecture
Refactor all three common config hooks (Claude, Codex, Gemini) to support
the new runtime merge architecture where:
- settingsConfig stores only custom (provider-specific) configuration
- commonConfigSnippet stores shared template configuration in database
- finalConfig is computed at runtime: merge(commonConfig, customConfig)
- Toggling common config only changes enabled state, not settingsConfig

Key changes across all hooks:
- Add finalConfig/finalEnv return value for merge preview
- Use configMerge utilities (computeFinalConfig, extractDifference)
- Remove direct config manipulation on toggle (no more inject/remove)
- Add proper TypeScript return type interfaces
- Simplify state management by removing unnecessary refs
- Improve code organization with clear section comments

This refactor enables:
- Clean separation between custom and common configuration
- Real-time merge preview in the UI
- Consistent behavior across Claude (JSON), Codex (TOML), and Gemini (env)
2026-01-26 14:09:13 +08:00
YoVinchen 5d48dd7908 fix(codex): add TOML validation and clearing sync for common config
- Add TomlValidationErrorCode type for structured error handling
- Add TOML syntax validation in getSnippetApplyError
- Trigger sync when clearing common config
- Add saveSequenceRef and enqueueSave for ordered async saves
- Add toast notification for sync failures
2026-01-25 03:42:32 +08:00
Jason efa653809b style: format code with Prettier 2026-01-05 21:53:01 +08:00
Jason 37396b9c70 fix(common-config): reset initialization flag when preset changes
The common config checkbox was only auto-enabled for the first preset
(custom) because hasInitializedNewMode ref was permanently locked to
true after first initialization.

Add selectedPresetId parameter to all three common config hooks and
reset the initialization flag when preset changes, allowing the
initialization logic to re-run for each preset switch.
2026-01-04 12:27:22 +08:00
Jason 63bb673bf2 refactor(common-config): extract snippet from editor content instead of active provider
- Change extraction source from current active provider to editor's live content
- Add i18n support for JSON parse error messages via invalid_json_format_error()
- Simplify API by removing unused providerId parameter
- Update button labels and error messages in zh/en/ja locales
2026-01-04 12:27:22 +08:00
Jason 188c94f2e3 feat(common-config): add extract from current provider functionality
- Add backend command to extract common config snippet from current provider
- Automatically extract common config on first run after importing default provider
- Auto-enable common config checkbox in new provider mode when snippet exists
- Refactor Gemini common config to operate on .env instead of config.json
- Add "Extract from Current" button to all three common config modals
- Update i18n translations for new extraction feature
2026-01-04 12:27:22 +08:00
Jason 154ff4c819 feat(config): unify common config snippets persistence across all apps
- Add unified `common_config_snippets` structure to MultiAppConfig
- Implement `get_common_config_snippet` and `set_common_config_snippet` commands
- Replace localStorage with config.json persistence for Codex and Gemini
- Auto-migrate legacy `claude_common_config_snippet` to new unified structure
- Deprecate individual API methods in favor of unified interface
- Add automatic migration from localStorage on first load

BREAKING CHANGE: Common config snippets now stored in unified `common_config_snippets` object instead of separate fields
2025-11-15 19:52:49 +08:00
Jason 57552b3159 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
2025-10-18 16:52:02 +08:00
Jason 8ce574bdd2 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
2025-10-16 21:04:32 +08:00