Commit Graph

1096 Commits

Author SHA1 Message Date
Roger Deng 6e8ee094f1 fix(usage): reduce price input step to 0.0001 for sub-cent precision (#2793)
The step was 0.01, preventing input of prices like DeepSeek's cache read
cost ($0.0028/million tokens). Extract step value to a constant and apply
to all four price fields.

Closes #2503
2026-05-18 11:38:32 +08:00
BlueOcean 0fb7fd12e5 feat: add Xiaomi MiMo Token Plan presets (#2803)
* feat: add Xiaomi MiMo token plan presets

* fix: update Xiaomi MiMo provider presets

* fix: align MiMo V2.5 model specs with official documentation

- Update maxTokens from 32000 to 131072 (128K) for mimo-v2.5-pro and mimo-v2.5
- Update contextWindow from 262144 to 1048576 (1M) for mimo-v2.5
- Aligns with official specs from Xiaomi MiMo documentation
- Ensures consistency between OpenClaw and OpenCode presets

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-18 10:38:03 +08:00
Zylo 8786f44c5a Fix race condition in useEffect hooks and type assertion bug (#2827)
- Add active flag pattern to 3 useEffect hooks in App.tsx to prevent
  event listener leaks when component unmounts before async setup completes
- Add guard check in useSettings.ts to prevent undefined from being
  stored in localStorage when payload.language is missing

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 09:36:44 +08:00
Jason c460a404dc Add Claude Desktop official preset
- Add Claude Desktop Official to the Claude Desktop preset list.
- Treat selected official presets as official mode in the form.
- Cover the official preset with a preset-order regression test.
2026-05-16 19:49:59 +08:00
Jason 9e3f168903 chore(release): bump version to 3.15.0 2026-05-16 11:21:18 +08:00
Jason 4a631b28c7 chore(i18n): simplify modelMappingOffHint to action-oriented copy 2026-05-15 23:33:48 +08:00
Jason ec8afd63ea refactor(presets): render presets in array order and prioritize partners
Remove the category-based grouping logic from ProviderPresetSelector,
letting the array position in each preset config file be the single
source of truth for display order. Move partner presets (PatewayAI,
火山Agentplan, BytePlus, DouBaoSeed) right after Shengsuanyun across
all 6 config files so they appear earlier in the UI.
2026-05-15 23:28:59 +08:00
Jason 9050442b65 feat(presets): add BytePlus provider preset as partner
Add BytePlus (international Volcengine) to Claude, Claude Desktop,
Hermes, OpenCode, and OpenClaw with byteplus icon, 256K context window,
and trilingual promotion text.
2026-05-15 22:45:04 +08:00
Jason d94eb6729b feat(presets): add 火山Agentplan provider preset as partner
Add Volcengine Ark Agentplan to Claude, Claude Desktop, Hermes,
OpenCode, and OpenClaw with huoshan icon and trilingual promotion.
2026-05-15 22:28:26 +08:00
Jason a0131c9a2b chore(presets): update DouBaoSeed endpoint, links, and add as partner
Switch Anthropic-format base URL from /api/coding to /api/compatible,
update website/apiKey URLs to Volcengine console with tracking params,
and promote DouBaoSeed to partner with trilingual promotion text.
2026-05-15 22:00:55 +08:00
Jason 58cd5302ae chore(presets): switch RelaxyCode icon to custom relaxcode.png
Replace the generic claude icon with a dedicated relaxcode.png icon
for the RelaxyCode provider presets.
2026-05-15 17:55:47 +08:00
Jason 3fd38b0a3d feat(presets): add RelaxyCode provider presets
Add RelaxyCode as a new third-party provider with support for:
- Claude Code preset (Anthropic native protocol)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (direct mode with passthrough routes)

RelaxyCode is an enterprise-grade AI programming platform providing
unified access to Claude Code, Codex, and Gemini CLI models.
2026-05-15 17:38:26 +08:00
Jason 18ffddbfa5 feat(presets): add RunAPI provider presets
Add RunAPI as a new partner provider with support for:
- Claude Code preset (Anthropic native protocol)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (direct mode with passthrough routes)
- OpenCode preset (@ai-sdk/anthropic)
- OpenClaw preset (anthropic-messages protocol)
- Hermes preset (anthropic_messages mode)
- Icon configuration (runapi.jpg)
- i18n support (zh/en/ja) with ¥14 free credit promotion

RunAPI is a high-performance AI model API gateway supporting 150+
mainstream models (OpenAI, Claude, Gemini, DeepSeek, Grok) with
prices as low as 10% of official rates.
2026-05-15 17:20:46 +08:00
Jason d6bbbf72f0 feat(presets): add ClaudeCN provider presets
Add ClaudeCN as a new partner provider with support for:
- Claude Code preset (Anthropic native protocol)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (direct mode with passthrough routes)
- OpenCode preset (@ai-sdk/anthropic)
- OpenClaw preset (anthropic-messages protocol)
- Hermes preset (anthropic_messages mode)
- Icon configuration (claudecn.png)
- i18n support (zh/en/ja) with enterprise service promotion

ClaudeCN is an enterprise-grade AI gateway operated by a registered
company, supporting enterprise procurement processes with corporate
payments, contracts, and compliance guarantees.
2026-05-14 23:28:07 +08:00
Jason df11df4d9c feat(presets): add ClaudeAPI provider presets
Add ClaudeAPI as a new partner provider with support for:
- Claude Code preset (using ANTHROPIC_AUTH_TOKEN field)
- Claude Desktop preset (direct mode with passthrough routes)
- Icon configuration (ClaudeApi.png)
- i18n support (zh/en/ja) with test credit promotion

ClaudeAPI provides official Anthropic API keys and AWS Bedrock
routing with support for Tool Use and 1M context.
2026-05-14 23:07:49 +08:00
Jason 4eb5543d9f refactor(presets): switch 20 Claude Desktop providers from proxy to direct mode
- Change mode from "proxy" to "direct" for 20 third-party/aggregator providers
- Simplify PipeLLM from mappedRoutes to passthroughRoutes for consistency
- Reduces unnecessary proxy layer overhead for providers that support direct API calls

Affected providers: ShengSuanYun, AIHubMix, DMXAPI, PackyAPI, PatewayAI,
Cubence, AIGoCode, RightCodes, AICodeMirror, AICoding, CrazyRouter,
SSSAICode, ModelVerse, CompShare, MicuAPI, CTOK, E-FlowCode,
VibeCodingAPI, LemonData, PipeLLM
2026-05-14 22:52:54 +08:00
Jason 08cd5ab56e feat(presets): add PatewayAI provider presets
Add PatewayAI as a new partner provider with support for:
- Claude Code preset (using ANTHROPIC_API_KEY field)
- Codex preset (gpt-5.5 model)
- Claude Desktop preset (proxy mode with passthrough routes)
- Icon configuration (pateway.jpg)
- i18n support (zh/en/ja) with $3 registration bonus promotion

PatewayAI provides reliable API routing services for Claude Code,
Codex, and Gemini models.
2026-05-14 22:36:45 +08:00
Jason b642ef0633 fix(failover): patch P1-P3 reliability gaps surfaced by team review
- Forwarder buffers non-streaming bodies and primes streaming first
  chunk before signaling success, so body timeouts and SSE first-chunk
  failures route through the circuit breaker instead of being recorded
  as success on response-header arrival
- Atomic enable-failover: switch to P1 before persisting the flag, and
  roll back auto-added queue entries when the switch is rejected
  (e.g. official providers)
- Hot-reload circuit breaker config on per-app proxy config change
  instead of waiting for a proxy restart
- FailoverToggle / FailoverQueueManager / AutoFailoverConfigPanel
  require proxy takeover for the active app; the backend command also
  rejects enabling when takeover is off
- ProviderHealthBadge consumes the backend is_healthy flag instead of
  hardcoding the 5-failure threshold

Cleanup:
- impl From<&AppProxyConfig> for CircuitBreakerConfig and use it from
  the command layer
- Collapse three identical TabsContent blocks into a single map
2026-05-14 21:35:02 +08:00
Jason 940161fb0e feat(providers): add routing support badges for Claude Code and Codex
Add visual indicators for routing capabilities on provider cards:
- Claude Code: "Needs Routing" badge for non-official providers with non-anthropic API formats
- Claude Code: "No Routing Support" badge for official providers
- Codex: "No Routing Support" badge for official providers

The badges help users understand which providers support format conversion through routing.
2026-05-14 17:51:42 +08:00
Jason cb45c22b63 chore(presets): migrate OpenClaudeCode to MicuAPI domain
Replace all openclaudecode.cn URLs with micuapi.ai across all
provider presets (Claude, Codex, Hermes, OpenClaw, OpenCode,
Claude Desktop). This includes website URLs, API key URLs, and
base URLs.
2026-05-14 15:41:52 +08:00
Jason 8dabb9fab9 chore(presets): update CrazyRouter API endpoints to cn subdomain
Update all CrazyRouter baseURL configurations from crazyrouter.com
to cn.crazyrouter.com across all supported applications (Claude,
Codex, Gemini, Hermes, OpenClaw, OpenCode, Claude Desktop).

Website and registration URLs remain unchanged.
2026-05-14 15:40:41 +08:00
Jason 99304ffcfd chore(partners): remove DDSHub partner integration
Remove DDSHub from all provider presets (Claude, Claude Desktop, Codex, Hermes),
i18n files (zh/en/ja), README docs, and icon system. Physical assets retained for
potential future restoration.
2026-05-14 15:35:35 +08:00
Jason 543e057e20 fix(providers): disable model test for third-party Claude providers
Most third-party Claude Code providers now reject requests from
non-official clients, so the model test button would just produce
noisy failures (or worse, trigger risk controls on the provider
side). Treat third-party Claude providers the same way as official /
Copilot / Codex OAuth: pass onTest=undefined so ProviderActions
renders the test button in its existing disabled visual state.
2026-05-14 15:26:54 +08:00
Jason 73bc4eb65d feat(codex-oauth): fetch model list from ChatGPT backend on demand
- Add `get_codex_oauth_models` Tauri command reusing the managed OAuth
  access token to hit `chatgpt.com/backend-api/codex/models`; HTTP and
  multi-shape JSON parsing live in `services::codex_oauth_models` so the
  command stays thin.
- Unify the Claude form's "fetch models" button across normal / Copilot /
  Codex OAuth presets, drop the auto-load effect for Copilot in favor of
  explicit clicks, and guard against stale responses with a requestId ref.
- Add Vitest coverage for both Copilot and Codex OAuth paths asserting no
  request on mount and the correct account id on click; add Rust unit
  tests for the four model-list payload shapes.
2026-05-14 15:03:31 +08:00
Jason 402570ce31 fix(usage): pricing routing, SSE lifecycle, and validation hardening
* model pricing routing: extend prefix-match families (gpt-/o1-o5/
  gemini-/deepseek-/qwen-/glm-/kimi-/minimax-) with per-family dash
  thresholds so short base IDs like gpt-5 no longer mis-match
  gpt-5-mini; strip ISO and 8-digit date suffixes via UTF-8-safe
  byte matching so claude-haiku-4-5-20251001 falls back to
  claude-haiku-4-5 pricing
* SSE collector: SseUsageFinishGuard (RAII) guarantees finish() on
  early return or panic; AtomicBool fast path lets push() skip the
  Mutex once first-event time is recorded
* validation: shared validate_cost_multiplier / validate_pricing_source
  helpers across DAO and service layers; PRICING_SOURCE_RESPONSE /
  PRICING_SOURCE_REQUEST constants replace string literals; price
  fields in update_model_pricing now reject empty / non-decimal /
  negative input before INSERT
* backfill: add backfill_missing_usage_costs_for_model so a single
  price edit only scans matching rows instead of the full log table;
  startup backfill remains full-scan
* session_usage{,_codex,_gemini}: share find_model_pricing helper from
  usage_stats; metadata_modified_nanos centralizes mtime precision
* frontend: NON_NEGATIVE_DECIMAL_REGEX + isNonNegativeDecimalString
  replace three copies of the same multiplier regex; isUnpricedUsage
  surfaces zero-cost rows that have usage tokens (cached per row to
  avoid double evaluation); invalidate usageKeys.all on pricing mutate
  so backfilled rows refresh
2026-05-14 11:53:51 +08:00
Jason 3c35972548 fix(proxy-ui): accept IPv6 listen addresses in ProxyPanel validation
The backend already understands `::` -> `::1` and wraps IPv6 literals
in brackets (services/proxy.rs), but the panel's save-time validator
only accepted localhost, 0.0.0.0, and IPv4 dotted-quads. Users who
wanted to listen on an IPv6 loopback had to bypass the UI and edit
config directly.

Add an isValidIpv6 helper that requires at least one ':' and round-trips
through `new URL('http://[<addr>]/')` so the platform's built-in IPv6
parser does the heavy lifting (covers compressed `::`, full 8-group
form, zone IDs). Update the invalidAddress copy in zh / en / ja so the
error message reflects the new accepted set.
2026-05-13 23:36:44 +08:00
Jason 4b57f7e113 feat(claude-code): role-based model mapping with display names and 1M flag
- Replace the four flat env inputs with a Sonnet/Opus/Haiku role table.
  Each row exposes ANTHROPIC_DEFAULT_*_MODEL plus a new display name
  field ANTHROPIC_DEFAULT_*_MODEL_NAME, and Sonnet/Opus gain a
  "Declare 1M" checkbox that toggles the [1M] suffix.
- Strip the [1M] context-capability marker before forwarding non-Copilot
  requests upstream. Copilot keeps its existing [1m]->-1m normalization.
- Claude Desktop import now consumes ANTHROPIC_DEFAULT_*_MODEL_NAME as
  label_override, closing the Claude Code -> Claude Desktop displayName
  pipeline; add_route's merge logic is shared between hashmap branches.
- Unify the [1M] marker as ONE_M_CONTEXT_MARKER across
  claude_desktop_config and proxy::model_mapper; rename the strip
  helper to strip_one_m_suffix_for_upstream.
- Collapse useModelState's seven duplicated useState initializers and
  the useEffect parse block into a single parseModelsFromConfig call.
- Add tests/hooks/useModelState.test.tsx and a Claude Desktop import
  test covering Kimi K2 -> label_override. i18n (en/ja/zh) updated.
2026-05-13 17:06:05 +08:00
Jason 84bac6dce6 refactor(claude-desktop): lock route IDs to sonnet/opus/haiku roles
Adapt to Claude Desktop 1.6259.1+ fail-all validation which only
accepts claude-(sonnet|opus|haiku)-* route IDs. Branded model names
(DeepSeek, Kimi, GLM, etc.) now live in a new labelOverride field
instead of being embedded in route IDs.

- Backend auto-repairs legacy unsafe routes to the next free
  sonnet/opus/haiku slot instead of erroring
- Frontend swaps the free-form route input for a role dropdown plus
  menu display name field
- Add CLAUDE_DESKTOP_ROLE_ROUTE_IDS as the single source of truth
  for role-to-route mapping; presets and form both consume it
- Drop the dead displayName alias on ClaudeDesktopModelRoute and the
  ineffective /v1/models display_name injection (UI ignores it)
- Update i18n (en/ja/zh) and form focus test for the new fields
2026-05-13 15:22:23 +08:00
Jason edf28b6422 feat(usage): filter-driven Hero with cache-normalized totals
- Normalize OpenAI/Gemini input_tokens semantics in SQL via the new
  fresh_input_sql helper (cache_read subtracted at query time, no data
  migration). Recovers correct cache hit rates for Codex/Gemini.
- Add get_usage_summary_by_app endpoint for per-app split (single
  UNION ALL + GROUP BY, avoids N+1).
- Replace UsageSummaryCards + AppBreakdownRail with a single
  filter-driven UsageHero card; clicking a filter button now truly
  changes the displayed numbers and the title accent color.
- Tighten KNOWN_APP_TYPES to the 3 app_types whose token data is
  reliably collected (claude/codex/gemini); hide claude-desktop,
  hermes, opencode, openclaw filter buttons and i18n keys.
- Flag cache_creation as N/A for OpenAI-style protocols (Codex,
  Gemini); show a "partial" tooltip when the All view mixes both
  protocol families.
2026-05-13 10:27:29 +08:00
Jason c12364a940 feat(claude-desktop): rework Claude Code import flow
- Derive route keys from the upstream model name (pass-through style)
  instead of fixed Claude aliases, and translate the legacy [1M] suffix
  into the supports1m field at the import boundary. Three Claude aliases
  mapped to the same upstream now collapse to a single route (e.g.
  MiniMax-M2 across SONNET/OPUS/HAIKU env produces one
  claude-MiniMax-M2 -> MiniMax-M2 row), with [1M] OR-aggregated.
- Add an import-time safety net that rebuilds claude-desktop-official
  when missing, so users who deleted it can recover via the normal
  import button without losing customizations on other providers.
- Hide API key and endpoint URL inputs in the official provider edit
  form to mirror Claude Code's behavior and prevent user confusion.
- Reword the empty-state import button label for clarity.
2026-05-12 21:31:30 +08:00
Jason 60a3628360 refactor(claude-desktop): replace [1M] suffix with supports1m field
inferenceModels entries now emit {name, supports1m: true} objects when
1M is enabled (plain strings otherwise), instead of appending a " [1M]"
suffix to model IDs. Route IDs and upstream model IDs are stored
verbatim; the suffix is rejected on input rather than silently stripped,
and proxy request mapping now requires an exact route_id match.
2026-05-12 17:40:32 +08:00
Jason ea4cdaad27 fix(ui): center Monitor badge icon in app switcher
The Monitor glyph's visual weight skews upward (screen rect dominates
while the stand is two thin lines), making it appear off-center inside
the 11px Claude Desktop badge. Add a per-badge offsetY config and
apply translateY(0.5px) to compensate.
2026-05-12 16:43:03 +08:00
Jason 44d4ea81af - 修复 Claude Desktop 模型输入框失焦
- 为动态模型行添加稳定 rowId,避免编辑模型 ID 时重挂载

- 增加模型映射和直连模型列表焦点保持回归测试
2026-05-12 11:47:45 +08:00
Jason 270f49a4a6 - 恢复 Claude Desktop 共享功能入口
- 将 Claude Desktop 的 Prompts、Skills、Sessions 映射到 Claude Code 配置

- 恢复 Claude Desktop 顶部功能按钮组

- 继续复用统一 MCP 面板入口
2026-05-12 11:36:57 +08:00
Jason 6a3c2fe0ba - 支持 Claude Desktop 使用 Copilot/Codex OAuth 供应商
- 放开本地路由托管 OAuth 供应商校验,允许动态 Token
- 新增 Claude Desktop Copilot/Codex 预设与账号选择
- 添加 OAuth proxy 回归测试
2026-05-12 11:30:11 +08:00
Jason 953b7cdcf9 refactor(claude-desktop): drop displayName from model route schema
Claude Desktop's new model menu reads model IDs directly and ignores the
display_name field, so a separate displayName slot added UI noise without
any product value. Collapse the routeId / model / displayName tuple down
to routeId / model, and let the route ID carry the user-visible name
through a non-editable claude- prefix rendered next to the input.

Drop display_name from ClaudeDesktopModelRoute, ClaudeDesktopDefaultRoute,
and ResolvedModelRoute on the Rust side plus the matching TS interfaces,
stop emitting it in /v1/models responses, derive route IDs from upstream
model IDs when picked via the model dropdown, and update zh/en/ja copy to
describe the new two-field layout.
2026-05-12 10:46:35 +08:00
Jason 417ad8149d fix(ui): hide empty toolbar capsule when Claude Desktop is active
Claude Desktop disables Skills, Prompts, Sessions, and MCP, which left
the secondary toolbar capsule next to the app switcher completely empty
but still rendered as a grey rounded pill. Wrap the capsule in an
activeApp !== "claude-desktop" guard so it disappears entirely, and
drop the two inner guards that this outer check makes redundant.
2026-05-11 23:15:57 +08:00
Jason 968c75bdbe feat(ui): use "Claude Code" label in app visibility settings
The app visibility section in Settings showed "Claude" for the first
entry, identical to "Claude Desktop" at a glance. Add a dedicated
i18n key apps.claudeCode and point the settings panel at it, while
leaving apps.claude untouched so other panels (MCP, Skills, Usage,
etc.) keep their shorter "Claude" label.
2026-05-11 23:15:30 +08:00
Jason ed41a7a7b9 feat(ui): distinguish Claude Code vs Claude Desktop in app switcher
The two Claude entries shared the same orange logo, making them hard to
tell apart at a glance. Rename the first entry to "Claude Code" and
overlay a Terminal badge on its logo; overlay a Monitor badge on the
Claude Desktop logo. Changes are scoped to AppSwitcher only; other
panels (MCP, Skills, Usage, etc.) continue to show "Claude".
2026-05-11 22:56:53 +08:00
Jason 2fc6753e42 chore(brand): surface ccswitch.io as the sole official website
Add an "Only Official Website" header to the three READMEs, an
About panel button, and a tray menu entry — all pointing to
ccswitch.io. Consolidates brand and SEO signals on the canonical
domain across docs, GUI, and system tray.
2026-05-11 15:25:48 +08:00
Jason e45470cd91 - fix(ci): restore frontend formatting and Linux clippy
- Format Claude Desktop provider presets with Prettier

- Gate platform-specific Claude Desktop path helpers behind cfg
2026-05-10 22:31:47 +08:00
Jason 50a873ca24 chore(icons): add ClaudeCN and RunAPI raster icons
Resized to 512x512 to match the existing extracted-icons size convention
(hermes.png / lemondata.png). Source uploads were oversized (7.3 MB
8635x8635 for ClaudeCN; 800x800 for RunAPI) and would have bloated the
bundle if imported as-is.

Note: not yet wired into index.ts / metadata.ts; register there when
they need to surface in the app UI.
2026-05-10 22:12:57 +08:00
Jason 5bbd83f7ca feat(claude-desktop): add 44 provider presets translated from Claude Code
- New src/config/claudeDesktopProviderPresets.ts with the Claude Code
  preset list re-shaped into Desktop's three-segment route format
  (routeId / upstreamModel / displayName); excludes OAuth providers,
  AWS Bedrock (no SigV4 support) and KAT-Coder (placeholder URL).
- Non-Claude upstream presets show upstream model id as displayName
  (e.g. deepseek-v4-pro) so the Desktop model list reflects what is
  actually being requested. OpenRouter/TheRouter/PIPELLM keep
  Sonnet/Opus/Haiku since their upstream really is Anthropic Claude.
- Wire ProviderPresetSelector into ClaudeDesktopProviderForm so
  selecting a preset back-fills baseUrl, mode, routes and apiFormat.
- Drop the hard-coded ANTHROPIC_AUTH_TOKEN write in handleSubmit so
  ANTHROPIC_API_KEY presets (LemonData / AiHubMix / Gemini Native)
  save under the correct env key, and clear the opposite key on switch.
- Hide the universal-providers tab for claude-desktop because its
  meta-driven routing has no analogue in the universal flat-env shape.
- Add apps."claude-desktop" i18n key (zh/en/ja) so the dialog tab
  label resolves instead of showing the literal key.
2026-05-09 17:19:09 +08:00
Jason 309f7609a5 refactor(claude-desktop): show badge only for providers requiring routing
Direct-mode providers no longer display a badge since routing is
optional for them. Proxy-mode providers now show "需要路由" / "Requires
routing" to clarify that local routing must be active.
2026-05-08 22:34:46 +08:00
Jason 21b9eb0430 refactor(claude-desktop): simplify model mapping UX
- Remove "Import from Claude" button from main provider list (keep in empty state)
- Remove "Desktop model" column from proxy mode mapping table; route names are now auto-generated
- Rename "upstream model" label to "requested model" and equalize column widths
- Rewrite model mapping hint and toggle description for end-user clarity
- Update validation messages and remove dead i18n keys (routeModelLabel)
2026-05-08 22:34:46 +08:00
Jason 2deee1097b refactor(claude-desktop): align provider form UI with Claude Code
- Rename field labels: "Gateway Base URL" → "API Endpoint", "Bearer Token" → "API Key"
- Change layout from 2-column grid to vertical sections matching Claude Code
- Reuse shared EndpointField component with format-aware amber hint box
- Replace native <datalist> with vendor-grouped ModelDropdown (OpenCode pattern)
- Move Fetch/Add buttons to section headers with compact sm styling
- Extract ModelDropdown to shared module, deduplicate from OpenCodeFormFields
- Extract renderActionButtons helper to eliminate proxy/direct button duplication
- Remove dead i18n keys (gatewayBaseUrl, bearerToken) from all 3 locales
2026-05-08 22:34:46 +08:00
Jason 34698723e3 fix(claude-desktop): remove proxy-stopped status alert
The route toggle in the top-right corner already communicates proxy
state; the extra warning banner was redundant and inconsistent with
other managed apps.
2026-05-08 22:34:46 +08:00
Jason 83f4e1d0ad refactor(claude-desktop): trim duplication in proxy and switch flows
- services/proxy.rs: collapse 10 repeated `OpenCode | OpenClaw | Hermes |
  ClaudeDesktop` match arms into `_` fallthroughs.
- claude_desktop_config.rs: extract a `with_rollback` closure shared by
  apply_provider_to_paths and restore_official_at_paths.
- useProviderActions.ts: replace the triple-nested ternary picking the
  switch-success toast message with a flat let/if/else block.

Net -36 lines. No behavior change; cargo test and pnpm typecheck pass.
2026-05-08 22:34:46 +08:00
Jason 8b3ad9caf9 feat(claude-desktop): add 3P provider switching with proxy gateway
Adds a new ClaudeDesktop AppType that writes Claude Desktop's third-party
inference profile under configLibrary/, sharing _meta.json with other
launchers (Ollama-compatible) so cc-switch can coexist with them.

Two switch modes:
- direct: provider already exposes claude-* / anthropic/claude-* model
  ids on Anthropic Messages, Claude Desktop connects to it directly.
- proxy: cc-switch's local proxy acts as the inference gateway,
  presenting only claude-* route names to Claude Desktop and mapping
  them to real upstream models. Required after Anthropic restricted
  Claude Desktop to claude-family ids.

Backend:
- New module claude_desktop_config with snapshot/rollback, official seed
  bypass, /claude-desktop/v1/{models,messages} routes, and a single
  source of truth for default proxy routes.
- Gateway token persisted in SQLite, validated on every proxied request.
- get_claude_desktop_status surfaces drift signals (stale models,
  missing routes, proxy stopped, base URL mismatch, missing token).

Frontend:
- Slim ClaudeDesktopProviderForm independent from ProviderForm,
  controlled by a top-level appId guard.
- ProviderList banner consumes the status query (5s polling) and
  renders actionable diagnostics.
- ClaudeDesktopRouteToggle in the header to start/stop the local
  gateway without touching takeover state.
- Three-locale i18n synchronised.
2026-05-08 22:34:46 +08:00
Butui Hu 1d44b1ba41 feat(universal-provider): add duplicate action for universal providers (#2416)
Signed-off-by: Hu Butui <hot123tea123@gmail.com>
2026-05-02 21:36:07 +08:00