Commit Graph

11 Commits

  • fix(linux): repair unresponsive UI on startup and full-screen panels
    Linux users reported the window UI (including native title bar buttons)
    couldn't receive clicks until manually maximizing and restoring the
    window. Root causes: (1) Tauri webview did not acquire focus on startup
    so first clicks were consumed by X11/Wayland click-to-activate
    (Tauri #10746, wry #637); (2) GTK surface input region failed to
    renegotiate on the visible:false + show() path under some
    WebKitGTK/compositor combinations.
    
    - Add linux_fix::nudge_main_window helper that performs set_focus plus
      a ±1px no-op resize after window show, with a 500ms reconciliation
      readback to compensate for dropped resize requests on slow
      compositors.
    - Wire the helper into every window re-show path: normal startup,
      deeplink, single_instance, tray show_main, and lightweight exit.
    - Set WEBKIT_DISABLE_COMPOSITING_MODE=1 at startup to avoid resize
      crashes and Wayland surface negotiation issues.
    - Remove data-tauri-drag-region on Linux from App.tsx header and the
      shared FullScreenPanel (used by all provider/MCP/workspace forms)
      to avoid Tauri #13440 in Wayland sessions. Extract drag-region
      constants to src/lib/platform.ts for reuse.
    
    All Rust changes are gated by #[cfg(target_os = "linux")]; frontend
    changes preserve macOS/Windows behavior via runtime isLinux() checks.
    Known limitation: tiling Wayland compositors ignore set_size, so
    GDK_BACKEND=x11 remains the user-side workaround.
  • feat: add Copilot optimizer to reduce premium interaction consumption
    Implement request classification, tool result merging, compact detection,
    deterministic request IDs, and warmup downgrade for Copilot proxy.
    
    The root cause was x-initiator being hardcoded to "user", making Copilot
    count every API request (including tool callbacks and agent continuations)
    as a separate premium interaction. The optimizer dynamically classifies
    requests as "user" or "agent" based on message content analysis.
    
    Closes #1813
  • feat(tray): collapse providers into submenus to prevent menu overflow
    Each app type (Claude/Codex/Gemini) now renders as a submenu instead
    of flat items, keeping the top-level tray menu compact regardless of
    provider count. The submenu label shows the current provider name
    (e.g. "Claude · OpenRouter") for at-a-glance visibility.
  • feat(terminal): add directory picker before launching Claude terminal (#1752)
    * Add directory picker before launching Claude terminal
    
    * fix(terminal): preserve cwd path and strip Windows verbatim prefix
    
    - Stop trimming non-empty paths so directories with leading/trailing
      spaces on Unix are handled correctly
    - Strip \\?\ extended-length prefix from canonicalized paths on Windows
      to prevent batch script cd failures
    
    * fix(terminal): restore UNC paths when stripping Windows verbatim prefix
    
    Handle \\?\UNC\server\share form separately from regular \\?\ prefix,
    converting it back to \\server\share so network/WSL directory paths
    remain valid in batch cd commands.
    
    * fix(terminal): use pushd for UNC paths in Windows batch launcher
    
    `cmd.exe` cannot set a UNC path (e.g. `\\wsl$\...`) as the current
    directory via `cd /d`; it errors with "CMD does not support UNC paths
    as current directories". Switch to `pushd` which temporarily maps the
    UNC share to a drive letter.
    
    Rename `build_windows_cd_command` → `build_windows_cwd_command` to
    reflect the broader semantics. Extract `build_windows_cwd_command_str`
    and `is_windows_unc_path` helpers for testability, and add unit tests
    covering drive paths, UNC paths, and batch metacharacter escaping.
    
    Also fix minor style issues: sort mod declarations alphabetically,
    add missing EOF newline in lightweight.rs, add explicit type annotation
    in streaming_responses test, and reformat tray menu builder chain.
  • chore(tray): hide Auto Failover shortcut from tray menu
    The Auto (Failover) toggle in the system tray is no longer shown.
    The feature remains fully functional via the Settings page.
    All related backend code (handle_auto_click, AUTO_SUFFIX, etc.)
    is preserved for easy re-enablement.
  • fix(failover): switch to P1 immediately when enabling auto failover
    Previously, enabling auto failover kept using the current provider until
    the first failure, causing inconsistency when the current provider was
    not in the failover queue. When stopping proxy, the restored config
    would not match user expectations.
    
    New behavior:
    - Enable auto failover = immediately switch to queue P1
    - Subsequent routing follows queue order (P1→P2→...)
    - Auto-add current provider to queue if queue is empty
    
    Changes:
    - Add switch_proxy_target() for hot-switching during proxy mode
    - Update provider_router to use queue order when failover enabled
    - Sync tray menu Auto click with the same logic
    - Update UI tooltips to reflect new semantics
    - Add tests for queue-only routing scenario
  • feat(tray): sync tray menu with app visibility settings
    Apply visibleApps setting to filter tray menu sections, so hidden apps
    no longer appear in the system tray menu.
  • Feat/provider individual config (#663)
    * 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 #636
    Fixes #583
    
    * fix(ui): sync toast theme with app setting
    
    * feat(settings): add log config management
    
    Fixes #612
    Fixes #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.
  • refactor(mcp): modularize MCP and tray menu logic
    Split mcp.rs (1135 lines) into focused modules:
    - validation.rs: server config validation
    - claude.rs: Claude MCP sync/import
    - codex.rs: Codex MCP sync (TOML handling)
    - gemini.rs: Gemini MCP sync/import
    
    Extract tray menu logic from lib.rs to tray.rs for better separation of concerns.