During app startup, iterate all app types and extract non-provider-specific
config fields from live configuration files into the database. This runs
only when no snippet exists yet for a given app type, enabling incremental
extraction as new apps are configured.
Revert the partial key-field merging refactoring introduced in 992dda5c,
along with two dependent commits (24fa8a18, 87604b18) that referenced
the now-removed ClaudeQuickToggles component.
The whitelist-based partial merge approach had critical issues:
- Non-whitelisted custom fields were lost during provider switching
- Backfill permanently stripped non-key fields from the database
- Whitelist required constant maintenance to track upstream changes
This restores the proven "full config overwrite + Common Config Snippet"
architecture where each provider stores its complete configuration and
shared settings are managed via a separate snippet mechanism.
Reverted commits:
- 24fa8a18: context-aware JSON editor hint + hide quick toggles
- 87604b18: hide ClaudeQuickToggles when creating
- 992dda5c: partial key-field merging refactoring
Restored:
- Full config snapshot write (write_live_snapshot) for Claude/Codex/Gemini
- Full config backfill (settings_config = live_config)
- Common Config Snippet UI and backend commands
- 6 frontend components/hooks for common config editing
- configApi barrel export and DB snippet methods
Removed:
- ClaudeQuickToggles component
- write_live_partial / backfill_key_fields / patch_claude_live
- All KEY_FIELDS constants
Previously OpenCode and OpenClaw auto-imported providers from live config
on app startup, which could confuse users. Now they follow the same
pattern as Claude/Codex/Gemini: manual import via the empty state button.
OMO and OMO Slim are OpenCode plugins, not standalone apps — users
should be able to fully remove them. Remove the count-based guard that
prevented deleting the last active provider, and clean up the now-unused
provider-count API surface across the full stack.
Each OMO provider now stores its complete configuration directly in
settings_config.otherFields instead of relying on a shared OmoGlobalConfig
merged at write time. This simplifies the data flow from a 4-tuple
(agents, categories, otherFields, useCommonConfig) to a 3-tuple and
eliminates an entire DB table, two Tauri commands, and ~1700 lines of
merge/sync code across frontend and backend.
Backend:
- Delete database/dao/omo.rs (OmoGlobalConfig struct + get/save methods)
- Remove get/set_config_snippet from settings DAO
- Remove get/set_common_config_snippet Tauri commands
- Replace merge_config() with build_config() in services/omo.rs
- Simplify OmoVariant (remove config_key, known_keys)
- Simplify import_from_local and build_local_file_data
- Rewrite all OMO service tests
Frontend:
- Delete OmoCommonConfigEditor.tsx and OmoGlobalConfigFields.tsx
- Delete src/lib/api/config.ts
- Remove OmoGlobalConfig type and merge preview functions
- Remove useGlobalConfig/useSaveGlobalConfig query hooks
- Simplify useOmoDraftState (remove all common config state)
- Replace OmoCommonConfigEditor with read-only JsonEditor preview
- Clean i18n keys (zh/en/ja)
Add open_workspace_directory Tauri command to open workspace/memory dirs
in the system file manager. Rename dailyMemory.createToday across all locales.
Add backend search command that performs case-insensitive matching
across all daily memory files, supporting both date and content queries.
Frontend includes animated search bar (⌘F), debounced input, snippet
display with match count badge, and search state preservation across
edits.
* refactor(provider): switch from full config overwrite to partial key-field merging
Replace the provider switching mechanism for Claude/Codex/Gemini from
full settings_config overwrite to partial key-field replacement, preserving
user's non-provider settings (plugins, MCP, permissions, etc.) across switches.
- Add write_live_partial() with per-app implementations for Claude (JSON env
merge), Codex (auth replace + TOML partial merge), and Gemini (env merge)
- Add backfill_key_fields() to extract only provider-specific fields when
saving live config back to provider entries
- Update switch_normal, sync_current_to_live, add, update to use partial merge
- Remove common config snippet feature for Claude/Codex/Gemini (no longer
needed with partial merging); preserve OMO common config
- Delete 6 frontend files (3 components + 3 hooks), clean up 11 modified files
- Remove backend extract_common_config_* methods, 3 Tauri commands,
CommonConfigSnippets struct, and related migration code
- Update integration tests to validate key-field-only backfill behavior
* refactor(cleanup): remove dead code and redundant MCP sync after partial-merge refactor
- Remove ConfigService legacy full-overwrite sync methods (~150 lines)
- Remove redundant McpService::sync_all_enabled from switch_normal
- Switch proxy fallback recovery from write_live_snapshot to write_live_partial
- Remove dead ProviderService::write_gemini_live wrapper
- Update tests to reflect partial-merge behavior (MCP preserved, not re-synced)
* feat(claude): add Quick Toggles for common Claude Code preferences
Add checkbox toggles for hideAttribution, alwaysThinking, and
enableTeammates that write directly to the live settings file via
RFC 7396 JSON Merge Patch. Mirror changes to the form editor using
form.watch for reactive updates.
* fix(provider): add missing key fields to partial-merge constants
Add provider-specific fields verified against official docs to prevent
key residue or loss during provider switching:
- Claude: CLAUDE_CODE_SUBAGENT_MODEL (env), model (top-level)
- Codex: review_model, plan_mode_reasoning_effort
- Gemini: GOOGLE_API_KEY (official alternative to GEMINI_API_KEY)
* fix(provider): expand partial-merge key fields for Bedrock, Vertex, Foundry and behavior settings
Add missing env/top-level fields to CLAUDE_KEY_ENV_FIELDS and
CLAUDE_KEY_TOP_LEVEL so that provider switching correctly replaces
(and clears) credentials and flags for AWS Bedrock, Google Vertex AI,
Microsoft Foundry, and provider behavior overrides like max output
tokens and prompt caching.
* feat(provider): add auth field selector for Claude providers (AUTH_TOKEN / API_KEY)
Allow users to choose between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY
when creating or editing custom Claude providers, persisted in meta.apiKeyField.
* refactor(preset): remove AiHubMix hardcoded API_KEY in favor of generic auth selector
AiHubMix was the only preset that hardcoded ANTHROPIC_API_KEY before the
generic auth field selector was introduced. Now that users can freely
choose between AUTH_TOKEN and API_KEY via the UI, remove the special-case
and default AiHubMix to the standard ANTHROPIC_AUTH_TOKEN.
Extract backup & restore into a standalone AccordionItem in Advanced settings.
Add configurable auto-backup interval (disabled/6h/12h/24h/48h/7d) and retention
count (3-50) via settings. Add per-backup rename with inline editing UI.
Four improvements to the database backup mechanism:
1. Auto backup before schema migration - creates a snapshot when
upgrading from an older database version, providing a safety net
beyond the existing SAVEPOINT rollback mechanism.
2. Periodic startup backup - checks on app launch whether the latest
backup is older than 24 hours and creates a new one if needed,
ensuring all users have recent backups regardless of usage patterns.
3. Backfill failure notification - switch now returns SwitchResult with
warnings instead of silently ignoring backfill errors, so users are
informed when their manual config changes may not have been saved.
4. Backup management UI - new BackupListSection in Settings > Data
Management showing all backup snapshots with restore capability,
including a confirmation dialog and automatic safety backup before
restore.
Remove the startup loop in lib.rs that auto-imported default providers
for Claude/Codex/Gemini. Move config snippet extraction logic into the
import_default_config command so it works when triggered manually.
Add an "Import Current Config" button to ProviderEmptyState, wired via
useMutation in ProviderList (shown only for standard apps). Update i18n
keys (zh/en/ja) with new button labels and revised empty state text.
Introduce OmoVariant struct with STANDARD/SLIM constants to eliminate
~250 lines of copy-pasted code across DAO, service, commands, and
frontend layers. Adding a new OMO variant now requires only a single
const declaration instead of duplicating ~400 lines.
Implement full OMO Slim profile management to align with ai-toolbox:
- Backend: Slim service methods, DAO, Tauri commands, plugin conflict handling
- Frontend: types, API, query hooks, form integration with isSlim parameterization
- Slim variant: 6 agents (no categories), separate config file and plugin name
- Mutual exclusion: standard OMO and Slim cannot coexist as plugins
- i18n: zh/en/ja translations for all Slim agent descriptions
- Fix EnvPanel visibleKeys using entry key name instead of array index
to prevent visibility state corruption after deletion
- Add NaN guard in AgentsDefaultsPanel numeric field parsing
- Validate provider id and models before importing from live config
- Upgrade import failure log level from debug to warn for OpenCode/OpenClaw
Add a dedicated panel to read/write OpenClaw's 6 workspace bootstrap files
(AGENTS.md, SOUL.md, USER.md, IDENTITY.md, TOOLS.md, MEMORY.md) directly
from ~/.openclaw/workspace/, with a whitelist-secured backend and Markdown
editor UI. Also fix prompt auto-import missing OpenCode/OpenClaw and the
PromptFormPanel filenameMap type exclusion.
- Add types for default model config (primary + fallbacks)
- Add types for model catalog/allowlist with aliases
- Extend OpenClawModelEntry with cost and contextWindow fields
- Add Tauri commands: get/set_openclaw_default_model, get/set_openclaw_model_catalog
- Create frontend API (src/lib/api/openclaw.ts)
- Add suggestedDefaults to provider presets with model metadata
- Add i18n translations (zh/en/ja) for openclawConfig.*
- Register openclaw_config module in lib.rs
- Add OpenClaw commands and provider import on startup
- Add OpenClaw branches to config and provider commands
- Add build_openclaw_settings() for deeplink imports
- Update MCP handlers with openclaw field in McpApps
- Add OpenClaw prompt file path
On some Linux systems with AMD GPUs (e.g., AMD Cezanne/Radeon Vega),
WebKitGTK's GPU process fails to initialize EGL, causing the app to
show a white screen on startup.
Root cause: `amdgpu_query_info(ACCEL_WORKING)` returns EACCES (-13),
which causes EGL display creation to fail with EGL_BAD_PARAMETER,
crashing the GPU process.
Fix: Use WebKitGTK's `set_hardware_acceleration_policy(Never)` API to
disable GPU acceleration on Linux, falling back to software rendering.
This is applied at startup via Tauri's `with_webview` API.
Co-authored-by: Naozhong AI <oursnoah@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(omo): integrate Oh My OpenCode profile management into Provider system
Adds full-stack OMO support: backend config read/write/import, OMO-specific
provider CRUD with exclusive switching, frontend profile editor with
agent/category/model configuration, global config management, and i18n support.
* feat(omo): add model/variant dropdowns from enabled providers
Replace model text inputs with Select dropdowns sourced from enabled
OpenCode providers, add thinking-level variant selection, and prevent
auto-enabling newly added OMO providers.
* fix(omo): use standard provider action styles for OMO switch button
* fix(omo): replace hardcoded isZh strings with proper i18n t() calls
* feat: init session manger
* feat: persist selected app to localStorage
- Save app selection when switching providers
- Restore last selected app on page load
* feat: persist current view to localStorage
- Save view selection when switching tabs
- Restore last selected view on page load
* styles: update ui
* feat: Improve macOS Terminal activation and refactor Kitty launch to use command with user's default shell.
* fix: session view
* feat: toc
* feat: Implement FlexSearch for improved session search functionality.
* feat: Redesign session manager search and filter UI for a more compact and dynamic experience.
* refactor: modularize session manager by extracting components and utility functions into dedicated files.
* feat: Enhance session terminal launching with support for iTerm2, Ghostty, WezTerm, and Alacritty, including UI and custom configuration options.
* feat: Conditionally render terminal selection and resume session buttons only on macOS.
- Add open_zip_file_dialog command for selecting ZIP files
- Add install_from_zip service method with recursive skill scanning
- Add install_skills_from_zip Tauri command
- Add frontend API methods and useInstallSkillsFromZip hook
- Add "Install from ZIP" button in Skills management page
- Support local skill ID format: local:{directory}
- Add i18n translations for new feature and error messages
* feat(db): add pricing config fields to proxy_config table
- Add default_cost_multiplier field per app type
- Add pricing_model_source field (request/response)
- Add request_model field to proxy_request_logs table
- Implement schema migration v5
* feat(api): add pricing config commands and provider meta fields
- Add get/set commands for default cost multiplier
- Add get/set commands for pricing model source
- Extend ProviderMeta with cost_multiplier and pricing_model_source
- Register new commands in Tauri invoke handler
* fix(proxy): apply cost multiplier to total cost only
- Move multiplier calculation from per-item to total cost
- Add resolve_pricing_config for provider-level override
- Include request_model and cost_multiplier in usage logs
- Return new fields in get_request_logs API
* feat(ui): add pricing config UI and usage log enhancements
- Add pricing config section to provider advanced settings
- Refactor PricingConfigPanel to compact table layout
- Display all three apps (Claude/Codex/Gemini) in one view
- Add multiplier column and request model display to logs
- Add frontend API wrappers for pricing config
* feat(i18n): add pricing config translations
- Add zh/en/ja translations for pricing defaults config
- Add translations for multiplier, requestModel, responseModel
- Add provider pricing config translations
* fix(pricing): align backfill cost calculation with real-time logic
- Fix backfill to deduct cache_read_tokens from input (avoid double billing)
- Apply multiplier only to total cost, not to each item
- Add multiplier display in request detail panel with i18n support
- Use AppError::localized for backend error messages
- Fix init_proxy_config_rows to use per-app default values
- Fix silent failure in set_default_cost_multiplier/set_pricing_model_source
- Add clippy allow annotation for test mutex across await
* style: format code with cargo fmt and prettier
* fix(tests): correct error type assertions in proxy DAO tests
The tests expected AppError::InvalidInput but the DAO functions use
AppError::localized() which returns AppError::Localized variant.
Updated assertions to match the correct error type with key validation.
---------
Co-authored-by: Jason <farion1231@gmail.com>
* refactor(ui): simplify UpdateBadge to minimal dot indicator
* feat(provider): add individual test and proxy config for providers
Add support for provider-specific model test and proxy configurations:
- Add ProviderTestConfig and ProviderProxyConfig types in Rust and TypeScript
- Create ProviderAdvancedConfig component with collapsible panels
- Update stream_check service to merge provider config with global config
- Proxy config UI follows global proxy style (single URL input)
Provider-level configs stored in meta field, no database schema changes needed.
* feat(ui): add failover toggle and improve proxy controls
- Add FailoverToggle component with slide animation
- Simplify ProxyToggle style to match FailoverToggle
- Add usage statistics button when proxy is active
- Fix i18n parameter passing for failover messages
- Add missing failover translation keys (inQueue, addQueue, priority)
- Replace AboutSection icon with app logo
* fix(proxy): support system proxy fallback and provider-level proxy config
- Remove no_proxy() calls in http_client.rs to allow system proxy fallback
- Add get_for_provider() to build HTTP client with provider-specific proxy
- Update forwarder.rs and stream_check.rs to use provider proxy config
- Fix EditProviderDialog.tsx to include provider.meta in useMemo deps
- Add useEffect in ProviderAdvancedConfig.tsx to sync expand state
Fixes#636Fixes#583
* fix(ui): sync toast theme with app setting
* feat(settings): add log config management
Fixes#612Fixes#514
* fix(proxy): increase request body size limit to 200MB
Fixes#666
* docs(proxy): update timeout config descriptions and defaults
Fixes#612
* fix(proxy): filter x-goog-api-key header to prevent duplication
* fix(proxy): prevent proxy recursion when system proxy points to localhost
Detect if HTTP_PROXY, HTTPS_PROXY, or ALL_PROXY environment variables
point to loopback addresses (localhost, 127.0.0.1), and bypass system
proxy in such cases to avoid infinite request loops.
* fix(i18n): add providerAdvanced i18n keys and fix failover toast parameter
- Add providerAdvanced.* i18n keys to en.json, zh.json, and ja.json
- Fix failover toggleFailed toast to pass detail parameter
- Remove Chinese fallback text from UI for English/Japanese users
* fix(tray): restore tray-provider events and enable Auto failover properly
- Emit provider-switched event on tray provider click (backward compatibility)
- Auto button now: starts proxy, takes over live config, enables failover
* fix(log): enable dynamic log level and single file mode
- Initialize log at Trace level for dynamic adjustment
- Change rotation strategy to KeepSome(1) for single file
- Set max file size to 1GB
- Delete old log file on startup for clean start
* fix(tray): fix clippy uninlined format args warning
Use inline format arguments: {app_type_str} instead of {}
* fix(provider): allow typing :// in endpoint URL inputs
Change input type from "url" to "text" to prevent browser
URL validation from blocking :// input.
Closes#681
* fix(stream-check): use Gemini native streaming API format
- Change endpoint from OpenAI-compatible to native streamGenerateContent
- Add alt=sse parameter for SSE format response
- Use x-goog-api-key header instead of Bearer token
- Convert request body to Gemini contents/parts format
* feat(proxy): add request logging for debugging
Add debug logs for outgoing requests including URL and body content
with byte size, matching the existing response logging format.
* fix(log): prevent usize underflow in KeepSome rotation strategy
KeepSome(n) internally computes n-2, so n=1 causes underflow.
Use KeepSome(2) as the minimum safe value.
Add startup import logic for OpenCode providers and MCP servers.
Unlike other apps that use replacement mode, OpenCode uses additive
mode where multiple providers can coexist in the config file.
- Create separate removeFromLiveConfig API for additive mode apps
(remove only removes from live config, not database)
- Fix useSwitchProviderMutation to invalidate opencodeLiveProviderIds
cache so button state updates correctly after add operation
- Show appropriate toast messages:
- Add: "已添加到配置" / "Added to config"
- Remove: "已从配置移除" / "Removed from config"
- Add i18n texts for addToConfigSuccess and removeFromConfigSuccess
OpenCode uses additive provider management where providers can exist in
the database but not necessarily in the live opencode.json config. This
commit implements proper isInConfig state:
Backend:
- Add get_opencode_live_provider_ids command to query live config
Frontend:
- Add getOpenCodeLiveProviderIds API method
- ProviderList queries live provider IDs and computes isInConfig
- ProviderCard receives and passes isInConfig to ProviderActions
- ProviderActions already handles the add/remove button logic
- Add import_opencode_providers_from_live command to provider.rs
- Register new command in lib.rs invoke_handler
- Update commands/mcp.rs: include OpenCode in sync_other_side logic
- Add McpService::import_from_opencode to import_mcp_from_apps
- Implement MCP sync/remove for OpenCode in services/mcp.rs
- sync_server_to_app_no_config now calls sync_single_server_to_opencode
- remove_server_from_app now calls remove_server_from_opencode
Add OpenCode as the 4th supported application with additive provider management:
- Add OpenCode variant to AppType enum with all related match statements
- Add enabled_opencode field to McpApps and SkillApps structures
- Add opencode field to McpRoot and PromptRoot
- Add database schema migration v3→v4 with enabled_opencode columns
- Add settings.rs support for opencode_config_dir and current_provider_opencode
- Create opencode_config.rs module for config file I/O operations
- Update all services (proxy, mcp, skill, provider, stream_check) for OpenCode
- Add OpenCode support to deeplink provider and MCP parsing
- Update commands/config.rs for OpenCode config status and paths
Key design decisions:
- OpenCode uses additive mode (no is_current needed, no proxy support)
- Config path: ~/.config/opencode/opencode.json
- MCP format: stdio→local, sse/http→remote conversion planned
- Stream check returns error (not yet implemented for OpenCode)
* feat(proxy): add thinking signature rectifier for Claude API
Add automatic request rectification when Anthropic API returns signature
validation errors. This improves compatibility when switching between
different Claude providers or when historical messages contain incompatible
thinking block signatures.
- Add thinking_rectifier.rs module with trigger detection and rectification
- Integrate rectifier into forwarder error handling flow
- Remove thinking/redacted_thinking blocks and signature fields on retry
- Delete top-level thinking field when assistant message lacks thinking prefix
* fix(proxy): complete rectifier retry path with failover switch and chain continuation
- Add failover switch trigger on rectifier retry success when provider differs from start
- Replace direct error return with error categorization on rectifier retry failure
- Continue failover chain for retryable errors instead of terminating early
* feat(proxy): add rectifier config with master switch
- Add RectifierConfig struct with enabled and requestThinkingSignature fields
- Update should_rectify_thinking_signature to check master switch first
- Add tests for master switch functionality
* feat(db): add rectifier config storage in settings table
Store rectifier config as JSON in single key for extensibility
* feat(commands): add get/set rectifier config commands
* feat(ui): add rectifier config panel in advanced settings
- Add RectifierConfigPanel component with master switch and thinking signature toggle
- Add API wrapper for rectifier config
- Add i18n translations for zh/en/ja
* feat(proxy): integrate rectifier config into request forwarding
- Load rectifier config from database in RequestContext
- Pass config to RequestForwarder for runtime checking
- Use should_rectify_thinking_signature with config parameter
* test(proxy): add nested JSON error detection test for thinking rectifier
* fix(proxy): resolve HalfOpen permit leak and RectifierConfig default values
- Fix RectifierConfig::default() to return enabled=true (was false due to derive)
- Add release_permit_neutral() for releasing permits without affecting health stats
- Fix 3 permit leak points in rectifier retry branches
- Add unit tests for default values and permit release
* style(ui): format ProviderCard style attribute
* fix(rectifier): add detection for signature field required error
Add support for detecting "signature: Field required" error pattern
in the thinking signature rectifier. This enables automatic request
rectification when upstream API returns this specific validation error.
* refactor(proxy): simplify logging for better readability
- Delete 17 verbose debug logs from handlers, streaming, and response_processor
- Convert excessive INFO logs to DEBUG level for internal processing details
- Add 2 critical INFO logs in forwarder.rs for failover scenarios:
- Log when switching to next provider after failure
- Log when all providers have been exhausted
- Fix clippy uninlined_format_args warning
This reduces log noise while maintaining visibility into key user-facing decisions.
* fix: replace unsafe unwrap() calls with proper error handling
- database/dao/mcp.rs: Use map_err for serde_json serialization
- database/dao/providers.rs: Use map_err for settings_config and meta serialization
- commands/misc.rs: Use expect() for compile-time regex pattern
- services/prompt.rs: Use unwrap_or_default() for SystemTime
- deeplink/provider.rs: Replace unwrap() with is_none_or pattern for Option checks
Reduces potential panic points from 26 to 1 (static regex init, safe).
* refactor(proxy): simplify verbose logging output
- Remove response JSON full output logging in response_processor
- Remove per-request INFO logs in provider_router (failover status, provider selection)
- Change model mapping log from INFO to DEBUG
- Change usage logging failure from INFO to WARN
- Remove redundant debug logs for circuit breaker operations
Reduces log noise significantly while preserving important warnings and errors.
* feat(proxy): add structured log codes for i18n support
Add error code system to proxy module logs for multi-language support:
- CB-001~006: Circuit breaker state transitions and triggers
- SRV-001~004: Proxy server lifecycle events
- FWD-001~002: Request forwarding and failover
- FO-001~005: Failover switch operations
- USG-001~002: Usage logging errors
Log format: [CODE] Chinese message
Frontend/log tools can map codes to any language.
New file: src/proxy/log_codes.rs - centralized code definitions
* chore: bump version to 3.9.1
* style: format code with prettier and rustfmt
* fix(ui): allow number inputs to be fully cleared before saving
- Convert numeric state to string type for controlled inputs
- Use isNaN() check instead of || fallback to allow 0 values
- Apply fix to ProxyPanel, CircuitBreakerConfigPanel,
AutoFailoverConfigPanel, and ModelTestConfigPanel
* feat(pricing): support @ separator in model name matching
- Refactor model name cleaning into chained method calls
- Add @ to - replacement (e.g., gpt-5.2-codex@low → gpt-5.2-codex-low)
- Add test case for @ separator matching
* feat(proxy): add global proxy settings support
Add ability to configure a global HTTP/HTTPS proxy for all outbound
requests including provider API calls, speed tests, and stream checks.
* fix(proxy): improve validation and error handling in proxy config panels
- Add StopTimeout/StopFailed error types for proper stop() error reporting
- Replace silent clamp with validation-and-block in config panels
- Add listenAddress format validation in ProxyPanel
- Use log_codes constants instead of hardcoded strings
- Use once_cell::Lazy for regex precompilation
* fix(proxy): harden error handling and input validation
- Handle RwLock poisoning in settings.rs with unwrap_or_else
- Add fallback for dirs::home_dir() in config modules
- Normalize localhost to 127.0.0.1 in ProxyPanel
- Format IPv6 addresses with brackets for valid URLs
- Strict port validation with pure digit regex
- Treat NaN as validation failure in config panels
- Log warning on cost_multiplier parse failure
- Align timeoutSeconds range to [0, 300] across all panels
* feat(proxy): add local proxy auto-scan and fix hot-reload
- Add scan_local_proxies command to detect common proxy ports
- Fix SkillService not using updated proxy after hot-reload
- Move global proxy settings to advanced tab
- Add error handling for scan failures
* fix(proxy): allow localhost input in proxy address field
* fix(proxy): restore request timeout and fix proxy hot-reload issues
- Add URL scheme validation in build_client (http/https/socks5/socks5h)
- Restore per-request timeout for speedtest, stream_check, usage_script, forwarder
- Fix set_global_proxy_url to validate before persisting to DB
- Mask proxy credentials in all log outputs
- Fix forwarder hot-reload by fetching client on each request
* style: format code with prettier
* fix(proxy): improve global proxy stability and error handling
- Fix RwLock silent failures with explicit error propagation
- Handle init() duplicate calls gracefully with warning log
- Align fallback client config with build_client settings
- Make scan_local_proxies async to avoid UI blocking
- Add mixed mode support for Clash 7890 port (http+socks5)
- Use multiple test targets for better proxy connectivity test
- Clear invalid proxy config on init failure
- Restore timeout constraints in usage_script
- Fix mask_url output for URLs without port
- Add structured error codes [GP-001 to GP-009]
* feat(proxy): add username/password authentication support
- Add separate username and password input fields
- Implement password visibility toggle with eye icon
- Add clear button to reset all proxy fields
- Auto-extract auth info from saved URL and merge on save
- Update i18n translations (zh/en/ja)
* fix(proxy): fix double encoding issue in proxy auth and add debug logs
- Remove encodeURIComponent in mergeAuth() since URL object's
username/password setters already do percent-encoding automatically
- Add GP-010 debug log for database read operations
- Add GP-011 debug log to track incoming URL info (length, has_auth)
- Fix username.trim() in fallback branch for consistent behavior
Merged PR #452 which adds:
- Terminal button for Claude providers to launch with provider-specific config
- Cross-platform support (macOS/Linux/Windows)
- Auto-cleanup of temporary config files
* feat(logging): add crash logging and improve log management
- Add panic hook to capture crash info to ~/.cc-switch/crash.log
- Records timestamp, app version, OS/arch, thread info
- Full stack trace with force_capture for release builds
- Safe error handling (no nested panics)
- Enable logging for both Debug and Release builds
- Info level for all builds
- Output to console and ~/.cc-switch/logs/
- 5MB max file size with rotation
- Add log cleanup on startup
- Keep only 2 most recent log files
- Works on all platforms
- Change panic strategy from "abort" to "unwind"
- Required for backtrace capture in release builds
* fix(logging): use OnceLock for config dir and add URL redaction
- Use OnceLock to support custom config directory override for crash.log
- Add redact_url_for_log() to protect sensitive URL parameters in logs
- Change verbose deep link logs from info to debug level
- Move Store refresh before panic_hook init to ensure correct path
---------
Co-authored-by: Jason <farion1231@gmail.com>
- Add user-friendly dialog when database init or schema migration fails
- Support retry mechanism instead of crashing the app
- Include bilingual (Chinese/English) error messages with troubleshooting tips
- Add comprehensive test for v3.8 → current schema migration path
- 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