Commit Graph

1177 Commits

  • fix(proxy): remove hardcoded ?beta=true injection, passthrough client query params
    - handlers.rs: add `uri` extractor to capture client's full path+query
    - claude.rs: remove ?beta=true injection from build_url(), update tests
    - stream_check.rs: remove ?beta=true from health check URL
    
    The proxy no longer injects ?beta=true into API URLs. Instead, query
    parameters sent by the Claude Code client are transparently passed through.
    This fixes duplicate ?beta=true issues and aligns with upstream behavior
    where the client already sends this parameter.
  • fix(opencode): add missing omo-slim category checks across add/form/mutation paths
    Several code paths only checked for "omo" category but missed "omo-slim",
    causing OMO Slim providers to be treated as regular OpenCode providers
    (triggering invalid write_live_snapshot, requiring manual provider key,
    and showing wrong form fields).
  • feat: Add AWS Bedrock Provider Support (AKSK & API Key) (#1047)
    * Add AWS Bedrock provider integration design document
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Add AWS Bedrock provider implementation plan
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Update implementation plan: add OpenCode Bedrock support
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add cloud_provider category to ProviderCategory type
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add AWS Bedrock (AKSK) Claude Code provider preset with tests
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add AWS Bedrock (API Key) Claude Code provider preset with tests
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add AWS Bedrock OpenCode provider preset with @ai-sdk/amazon-bedrock
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * docs: add AWS Bedrock provider feature summary for PR
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * chore: remove internal planning documents
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * docs: add AWS Bedrock support to README (EN/ZH/JA)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Add AWS Bedrock UI merge design document
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Add AWS Bedrock UI merge implementation plan
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: skip optional template values in validation
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: support isSecret template fields and hide base URL for Bedrock
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add Bedrock validation, cleanup, and isBedrock prop in ProviderForm
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: extend TemplateValueConfig and merge Bedrock presets
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: mask Bedrock API Key as secret and support GovCloud regions
    
    - Add isSecret: true to BEDROCK_API_KEY template value
    - Update region regex to support multi-segment regions (us-gov-west-1)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * style: replace AWS icon with updated logo
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * style: replace AWS icon with updated logo
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * style: replace AWS icon with new PNG image
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: address code review findings
    
    - Fix AWS icon: use SVG with embedded <image> instead of raw <img> tag
    - Hide duplicate ApiKeySection for Bedrock (auth via template fields only)
    - Guard settingsConfig cleanup against unresolved template placeholders
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * chore: remove planning documents
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * refactor: address PR review - split Bedrock into two presets, restore SVG icon
    
    Based on maintainer review feedback on PR #1047:
    
    1. Split merged "AWS Bedrock" back into two separate presets:
       - "AWS Bedrock (AKSK)": uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
       - "AWS Bedrock (API Key)": uses top-level apiKey field via standard UI input
    
    2. Restore aws.svg to pure vector SVG (was PNG-in-SVG)
    
    3. Remove all Bedrock-specific logic from shared components:
       - Remove isBedrock prop from ClaudeFormFields
       - Remove Bedrock validation/cleanup blocks from ProviderForm
       - Remove optional/isSecret from TemplateValueConfig
       - Remove optional skip from useTemplateValues
    
    4. Add cloud_provider category handling:
       - Skip API Key/Base URL required validation
       - Hide Speed Test and Base URL for cloud_provider
       - Hide API format selector for cloud_provider (always Anthropic)
       - Show API Key input only when config has apiKey field
    
    5. Fix providerConfigUtils to support top-level apiKey:
       - getApiKeyFromConfig: check config.apiKey before env fields
       - setApiKeyInConfig: write to config.apiKey when present
       - hasApiKeyField: detect top-level apiKey property
    
    6. Add OpenClaw Bedrock preset (bedrock-converse-stream protocol)
    
    7. Update model IDs:
       - Sonnet: global.anthropic.claude-sonnet-4-6
       - Opus: global.anthropic.claude-opus-4-6-v1
       - Haiku: global.anthropic.claude-haiku-4-5-20251001-v1:0
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(test): align Bedrock API Key test assertions with preset implementation
    
    The API Key preset was refactored to use standard UI input (apiKey: "")
    instead of template variables, but the tests were not updated accordingly.
    
    ---------
    
    Co-authored-by: root <root@ip-10-0-11-189.ap-northeast-1.compute.internal>
    Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
    Co-authored-by: Jason <farion1231@gmail.com>
  • feat(workspace): make directory paths clickable and rename "Today's Note" to "Add Memory"
    Add open_workspace_directory Tauri command to open workspace/memory dirs
    in the system file manager. Rename dailyMemory.createToday across all locales.
  • feat(workspace): add full-text search for daily memory files
    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.
  • feat(preset): update domestic model providers to latest versions
    - MiniMax: M2.1 → M2.5
    - Zhipu GLM: glm-4.7 → glm-5
    - BaiLing: Ling-1T → Ling-2.5-1T
    - DouBaoSeed: doubao-seed-code-preview-latest → doubao-seed-2-0-code-preview-latest
    - Qwen (Bailian): qwen3-max → qwen3.5-plus
  • refactor(provider): switch from full config overwrite to partial key-field merging (#1098)
    * 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.
  • feat(backup): add hourly periodic backup timer during runtime
    Previously periodic backup only checked on startup. Now spawns a
    tokio interval task that checks every hour while the app is running.
  • feat(backup): add independent backup panel, configurable policy, and rename support
    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.
  • feat(backup): add pre-migration backup, periodic backup, backfill warning, and backup management 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.
  • feat(settings): add first-run confirmation dialogs for proxy and usage features
    Prevent accidental activation of advanced features by showing a one-time
    info dialog. Once confirmed, the flag is persisted in settings.json and
    the dialog never appears again.
    
    - Proxy: confirmation when toggling proxy server ON for the first time
    - Usage: confirmation when enabling usage query inside UsageScriptModal
    - Enhanced ConfirmDialog with "info" variant (blue icon + default button)
    - Added i18n translations for zh, en, ja
  • feat(toolbar): add smooth transition animation for AppSwitcher compact toggle
    Replace conditional rendering with always-rendered span driven by CSS
    max-width + opacity animation. Add time-lock in useAutoCompact to prevent
    ResizeObserver flicker during expand animation.
  • fix(toolbar): remove height constraint that clipped AppSwitcher
    The toolbar wrapper's fixed h-[32px] was smaller than AppSwitcher's
    natural 40px height (32px buttons + 8px padding), causing visual
    clipping. Removed the constraint and let flex layout handle sizing
    within the 64px header.
  • feat(toolbar): auto-compact AppSwitcher based on available width
    Replace hardcoded app count threshold with ResizeObserver-based
    detection. Uses a two-layer layout (overflow-hidden outer + shrink-0
    inner) to avoid the compact/normal oscillation problem.
  • feat(sessions): default filter to current app when entering session page
    Navigate directly to the active app's sessions instead of showing all.
  • feat(sessions): add session browsing for OpenCode and OpenClaw
    Add two new session providers following the existing convention-based
    pattern. OpenCode reads three-layer JSON storage, OpenClaw parses JSONL
    event streams. Wire up backend dispatch, frontend filter dropdown, icon
    mappings, toolbar button for OpenClaw, and i18n subtitle updates.
  • refactor(settings): split Advanced tab into Proxy tab and move Pricing to Usage
    Extract proxy-related accordion items (Local Proxy, Failover, Rectifier,
    Global Outbound Proxy) into a dedicated Proxy tab via ProxyTabContent
    component. Move Pricing config panel to UsageDashboard as a collapsible
    accordion. This reduces SettingsPage from ~716 to ~426 lines and improves
    settings discoverability with a 5-tab layout: General | Proxy | Advanced |
    Usage | About.
  • feat: more granular local environment checks (#870)
    * feat: more granular local environment checks
    
    * refactor: improve PR #870 with i18n, shadcn Select, and testable helpers
    
    - Extract is_valid_shell, is_valid_shell_flag, default_flag_for_shell
      to module-level #[cfg(windows)] functions for testability
    - Add unit tests for extracted helper functions
    - Replace native <select> with shadcn/ui Select components
    - Extract env badge ternary to ENV_BADGE_CONFIG Record lookup
    - Add i18n keys for env badges and WSL selectors (zh/en/ja)
    - Unify initial useEffect load path with loadAllToolVersions()
    
    * fix: prevent useEffect re-firing on wslShellByTool changes
    
    The useEffect that loads initial tool versions depended on
    loadAllToolVersions, which in turn depended on wslShellByTool.
    This caused a full re-fetch of all 4 tools every time the user
    changed a WSL shell or flag, racing with the single-tool refresh.
    
    Fix: use empty deps [] since this is a mount-only effect. The
    refresh button and shell/flag handlers cover subsequent updates.
    
    ---------
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • refactor(provider): replace startup auto-import with manual import button
    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.
  • fix(query): remove auto-import side effect from useProvidersQuery queryFn
    Users now trigger provider import manually via the empty state button,
    keeping queryFn pure and preventing unintended imports on mount/refocus.
  • 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.
  • refactor(openclaw): make primary model read-only in Agents panel
    The primary model field in the Agents defaults panel now displays as
    read-only, eliminating the duplicate edit entry with the "Set as Default
    Model" button on provider cards. Fallback models and runtime parameters
    remain editable.
  • fix(i18n): clarify OpenClaw default model button labels
    Rename "Enable/Default" to "Set Default/Current Default" across
    zh/en/ja locales and widen button to fit longer text.
  • fix(workspace): sort daily memory by date and inline into file grid
    - Sort daily memory list by filename (YYYY-MM-DD.md) instead of mtime
      so editing an older file no longer bumps it to the top
    - Move daily memory card inline with workspace MD file buttons
    - Shorten card description across all locales
    - Defer file creation until user actually saves (no empty file on create)
  • feat(workspace): add daily memory file management for OpenClaw
    Add browse, edit, create and delete support for daily memory files
    (~/.openclaw/workspace/memory/YYYY-MM-DD.md) in the Workspace panel.
  • chore(ui): hide stream check / model test config panels
    The stream check feature is unreliable due to diverse provider request
    formats. Comment out the model test config UI in settings page, provider
    advanced config, and the test button in provider actions. Backend code
    and i18n keys are preserved for future restoration.
  • feat(settings): add enableLocalProxy toggle to gate main page proxy UI
    New users often accidentally trigger ProxyToggle/FailoverToggle on the
    main page. Add a settings toggle (default off) so the proxy controls
    only appear when explicitly enabled. The proxy service start/stop in
    settings remains independent of this visibility flag.
  • refactor(omo): deduplicate OMO/OMO Slim via OmoVariant parameterization
    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.
  • feat(omo): add OMO Slim (oh-my-opencode-slim) support
    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
  • refactor(forms): extract OpenCode/OMO/OpenClaw state from ProviderForm into dedicated hooks
    Split ProviderForm.tsx (2227 → 1526 lines) by extracting:
    - opencodeFormUtils.ts: pure functions and default config constants
    - useOmoModelSource: OMO model source collection from OpenCode providers
    - useOpencodeFormState: OpenCode provider form state and handlers
    - useOmoDraftState: OMO profile draft editing state
    - useOpenclawFormState: OpenClaw provider form state and handlers
  • fix(ui): add vertical spacing between directory settings sections
    Replace React Fragment with a div using space-y-6 to add proper
    vertical spacing between the app config directory and directory
    override sections in Settings > Advanced > Directory Settings.
  • fix: Don't add ?beta=true to OpenAI Chat Completions endpoints (#1052)
    Fixes Nvidia provider and other providers using apiFormat="openai_chat".
    
    The ClaudeAdapter::build_url() method was incorrectly adding ?beta=true
    to both /v1/messages and /v1/chat/completions endpoints. This caused
    the Nvidia provider to fail because:
    
    1. Nvidia uses apiFormat="openai_chat"
    2. Requests are transformed to OpenAI format and sent to /v1/chat/completions
    3. The URL gets ?beta=true appended (Anthropic-specific parameter)
    4. Nvidia's API rejects requests with this parameter
    
    Fix:
    - Only add ?beta=true to /v1/messages endpoint
    - Exclude /v1/chat/completions from getting this parameter
    
    Tested:
    - Anthropic /v1/messages still gets ?beta=true ✓
    - OpenAI Chat Completions /v1/chat/completions does NOT get ?beta=true ✓
    - All 13 Claude adapter tests pass ✓
    
    Co-authored-by: jnorthrup <jnorthrup@example.com>
  • feat(ui): add quick config toggles to Claude config editor (#1012)
    Add 3 quick-toggle checkboxes above the JSON editor in Claude provider settings:
    - Hide AI Attribution (sets attribution.commit/pr to empty string)
    - Extended Thinking (sets alwaysThinkingEnabled to true)
    - Teammates Mode (sets env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS to "1")
    
    Uses local state to keep toggles and JsonEditor in sync without
    triggering ProviderForm re-renders. Includes i18n for zh/en/ja.
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • feat(webdav): follow-up 补齐自动同步与大文件防护 (#1043)
    * feat(webdav): add robust auto sync with failure feedback
    
    (cherry picked from commit bb6760124a62a964b36902c004e173534910728f)
    
    * fix(webdav): enforce bounded download and extraction size
    
    (cherry picked from commit 7777d6ec2b9bba07c8bbba9b04fe3ea6b15e0e79)
    
    * fix(webdav): only show auto-sync callout for auto-source errors
    
    * refactor(webdav): remove services->commands auto-sync dependency
  • Fix/skill zip symlink resolution (#1040)
    * fix(skill): resolve symlinks in ZIP extraction for GitHub repos (#1001)
    
    - detect symlink entries via is_symlink() during ZIP extraction and collect target paths
    
    - add resolve_symlinks_in_dir() to copy symlink target content into link location
    
    - canonicalize base_dir to fix macOS /tmp → /private/tmp path comparison issue
    
    - add path traversal safety check to block symlinks pointing outside repo boundary
    
    - apply symlink resolution to both download_and_extract and extract_local_zip paths
    
    Closes https://github.com/farion1231/cc-switch/issues/1001
    
    * fix(skill): change search to match name and repo instead of description
    
    * feat(skill): support importing skills from ~/.agents/skills/ directory
    
    - Scan ~/.agents/skills/ in scan_unmanaged() for skill discovery
    - Parse ~/.agents/.skill-lock.json to extract repo owner/name metadata
    - Auto-add discovered repos to skill_repos management on import
    - Add path field to UnmanagedSkill to show discovered location in UI
    
    Closes #980
    
    * fix(skill): use metadata name or ZIP filename for root-level SKILL.md imports (#1000)
    
    When a ZIP contains SKILL.md at the root without a wrapper directory,
    the install name was derived from the temp directory name (e.g. .tmpDZKGpF).
    Now falls back to SKILL.md frontmatter name, then ZIP filename stem.
    
    * feat(skill): scan ~/.cc-switch/skills/ for unmanaged skill discovery and import
    
    * refactor(skill): unify scan/import logic with lock file skillPath and repo saving
    
    - Deduplicate scan_unmanaged and import_from_apps using shared source list
    - Replace hand-written AppType match with as_str() and AppType::all()
    - Extract read_skill_name_desc, build_repo_info_from_lock, save_repos_from_lock helpers
    - Add SkillApps::from_labels for building enable state from source labels
    - Parse skillPath from .skill-lock.json for correct readme URLs
    - Save skill repos to skill_repos table in both import and migration paths
    
    * fix(skill): resolve symlink and path traversal issues in ZIP skill import
    
    * fix(skill): separate source path validation and add canonicalization for symlink safety
  • fix(opencode): 补齐 install.sh 安装路径检测 (#988)
    补齐 OpenCode 路径扫描来源(按官方 install.sh 优先级):
      OPENCODE_INSTALL_DIR > XDG_BIN_DIR > ~/bin > ~/.opencode/bin
    保留并增强 Go 安装路径扫描(~/go/bin、GOPATH/*/bin)。
    
    区分单值环境变量(push_env_single_dir)与 path-list 环境变量
    (extend_from_path_list),避免对 OPENCODE_INSTALL_DIR 等单值
    变量误用 split_paths。
    
    增加路径去重逻辑(push_unique_path),避免重复扫描。
    
    增加跨平台可执行候选逻辑(tool_executable_candidates):
      Windows: .cmd / .exe / 裸命令
      Unix:    裸命令
    
    将 PATH 拼接提至外层循环,减少重复 syscall。
    
    增加单元测试覆盖路径拼装、去重及 Windows 候选顺序。
    
    Closes #958
    
    Co-authored-by: Warp <agent@warp.dev>