Introduce ProviderType enum to distinguish between different provider
implementations (Claude, ClaudeAuth, Codex, Gemini, GeminiCli, OpenRouter).
This enables proper authentication handling and request transformation
based on the actual provider type rather than just AppType.
- Add ProviderType enum with detection logic from config
- Enhance Claude adapter with OpenRouter detection
- Enhance Gemini adapter with CLI mode detection
- Add helper methods for provider type inference
Add UsageDashboard with summary cards, trend chart, and data tables.
Implement model pricing configuration panel.
Add request log viewer with filtering and detail panel.
Add request logger with automatic cost calculation.
Implement token parser for Claude/OpenAI/Gemini responses.
Add cost calculator based on model pricing configuration.
Replace Node.js process.platform check with navigator.userAgent-based
detection from @/lib/platform. The previous implementation using
process.platform failed in Tauri's browser environment, causing
Windows platform to always return false and not apply the required
'cmd /c' wrapper for npx commands.
This fix ensures that on Windows, MCP presets like sequential-thinking
correctly use 'cmd /c npx' format instead of direct 'npx', eliminating
the warning: "Windows requires 'cmd /c' wrapper to execute npx"
Changes:
- Import isWindows() from @/lib/platform instead of defining locally
- Remove incorrect process.platform-based detection
- Now properly detects Windows in browser/WebView environment
Move 1px of horizontal padding from outer container to inner scroll
container, providing buffer space for the hover scale-[1.01] effect
without being cut off by overflow-hidden.
This major refactoring introduces a modular provider adapter architecture
to support format transformation between different AI API formats.
New features:
- Add ProviderAdapter trait for unified provider abstraction
- Implement Claude, Codex, and Gemini adapters with specific logic
- Add Anthropic ↔ OpenAI format transformation for OpenRouter compatibility
- Support model mapping from provider configuration (ANTHROPIC_MODEL, etc.)
- Add OpenRouter preset to Claude provider presets
Refactoring:
- Extract authentication logic into auth.rs with AuthInfo and AuthStrategy
- Move URL building and request transformation to individual adapters
- Simplify ProviderRouter to only use proxy target providers
- Refactor RequestForwarder to use adapter-based request/response handling
- Use whitelist mode for header forwarding (only pass necessary headers)
Architecture:
- providers/adapter.rs: ProviderAdapter trait definition
- providers/auth.rs: AuthInfo, AuthStrategy types
- providers/claude.rs: Claude adapter with OpenRouter detection
- providers/codex.rs: Codex (OpenAI) adapter
- providers/gemini.rs: Gemini (Google) adapter
- providers/models/: Anthropic and OpenAI API data models
- providers/transform.rs: Bidirectional format transformation
- Add #[allow(dead_code)] to unused ProviderUnhealthy variant
- Inline format string arguments in handlers.rs and codex.rs log macros
- Refactor error response handling to properly pass through upstream errors
- Add URL deduplication logic for /v1/v1 paths in CodexAdapter
- Refactor URL construction with version path deduplication (/v1, /v1beta)
- Preserve query parameters for Gemini API requests
- Support GOOGLE_GEMINI_API_KEY field name (with fallback)
- Change default proxy port from 5000 to 15721
- Fix test: use Option type for is_proxy_target field
Providers page was using DndContext which may interfere with scroll wheel
events on Linux/Ubuntu WebKitGTK. Added independent scroll containers
with `overflow-y-auto` to all main pages, matching the pattern already
used by the MCP panel which works correctly.
Changes:
- App.tsx: Wrap ProviderList in independent scroll container
- SkillsPage: Use consistent h-[calc(100vh-8rem)] layout
- SettingsPage: Add overflow-hidden and overflow-x-hidden for consistency
Simplify proxy control interface and fix database persistence issues:
Backend Fixes:
- Fix NOT NULL constraint error in proxy_config.created_at field
* Use COALESCE to preserve created_at on updates
* Ensure proper INSERT OR REPLACE behavior
- Remove redundant enabled field validation on startup
* Auto-enable when user clicks start button
* Persist enabled state after successful start
- Preserve enabled state during config updates
* Prevent accidental service shutdown on config save
Frontend Improvements:
- Remove duplicate proxy enable switch from settings dialog
* Keep only runtime toggle in ProxyPanel
* Simplify user experience with single control point
- Hide proxy target button when proxy service is stopped
* Add isProxyRunning prop to ProviderCard
* Conditionally render proxy controls based on service status
- Update form schema to omit enabled field
* Managed automatically by backend
Files: 5 changed, 81 insertions(+), 94 deletions(-)
- Update README_JA.md to reference Japanese screenshots
- Add Japanese screenshots (main-ja.png, add-ja.png)
- Update English and Chinese screenshots with latest UI
- Remove outdated README_i18n.md documentation
- Remove `.replace(/\/+$/, "")` from all base URL handlers in useBaseUrlState.ts
- Remove trailing slash stripping in useCodexConfigState.ts
- Remove trailing slash normalization in providerConfigUtils.ts setCodexBaseUrl()
- Update i18n hints (en/ja/zh) to instruct users to avoid trailing slashes
This gives users explicit control over URL format rather than silently modifying input.
The selected provider's visual highlight (background, border, glow)
was being overridden by .glass-card base styles due to CSS specificity.
Add dedicated .glass-card-active class to ensure active state persists.
The dialog backgrounds were transparent because Tailwind 3 requires explicit
color mappings in the config to use CSS variables. Added standard shadcn/ui
color mappings (background, foreground, card, primary, etc.) and removed
unnecessary overlayClassName overrides from dialog components.
- Use zIndex="alert" and semi-transparent overlay for consistency
- Apply border-b-0/border-t-0 bg-transparent to header/footer
- Replace emerald accent with blue to match app theme
- Use Input component instead of raw input elements
- Simplify button variants (outline for cancel)
The auto-launch crate has different API signatures on each platform:
- Windows/Linux: AutoLaunch::new() takes 3 arguments
- macOS: AutoLaunch::new() takes 4 arguments (includes hidden param)
The previous code used #[cfg(not(target_os = "windows"))] which incorrectly
applied macOS's 4-argument signature to Linux, causing build failures.
Switch to AutoLaunchBuilder which handles platform differences internally.
- Add MiniMax en preset with international API endpoint (minimaxi.io)
- Split MiniMax partner promotion into CN and EN versions
- Remove unnecessary icon config from Aliyun and Alibaba Lingma presets
- Add CHANGELOG entry for v3.8.0
- Update README.md and README_ZH.md with v3.8.0 features
- Add Japanese README (README_JA.md)
- Add release notes in English, Chinese, and Japanese
Remove the skillsPath field from SkillRepo and Skill structs since
recursive scanning now automatically discovers skills in all directories.
Simplify the UI by removing the path input field.
- Add JsonEditor mock to McpFormModal tests (component uses CodeMirror
instead of Textarea)
- Fix assertion for missing command error message
- Update ImportExportSection tests for new button behavior and file
display format
- Run cargo fmt to fix Rust code formatting (lib.rs)
- Add missing i18n keys: migration.success, agents.title (zh/en/ja)
- Replace hardcoded strings "Agents" and "MCP" with t() calls in App.tsx
- Fix test mocks and assertions:
- Add providersApi.updateTrayMenu to useSettings.test.tsx mock
- Update SettingsPage mock path in App.test.tsx
- Fix toast message assertion in integration/SettingsDialog.test.tsx
- Add autoSaveSettings to SettingsDialog component test mock
- Fix loading state test to check spinner instead of title
- Update import button name matching for selected file state
- Fix save button test to switch to advanced tab first
- Remove obsolete cancel button test (button no longer exists)
Test results improved from 99 passed / 17 failed to 104 passed / 11 failed
- Add complete Japanese translation file (ja.json)
- Update frontend types and hooks to support "ja" language option
- Add Japanese tray menu texts in Rust backend
- Add Japanese option to language settings component
- Update Zod schema to include Japanese language validation
- Add test case for Japanese language preference
- Update i18n documentation to reflect three-language support
- Replace global `is_empty_for_first_import()` with independent checks:
- `is_mcp_table_empty()` for MCP server imports
- `is_prompts_table_empty()` for prompt imports
- Skills and providers already have built-in idempotency checks
- Fix misleading logs in provider import:
- Change `import_default_config` return type from `Result<()>` to `Result<bool>`
- Return `true` when actually imported, `false` when skipped
- Only log success message when import actually occurred
- Add idempotency protection to `import_from_file_on_first_launch`
This allows each data type to be independently recovered if deleted,
rather than requiring all tables to be empty for any import to trigger.