Commit Graph

1768 Commits

Author SHA1 Message Date
Jason ee2d634d89 feat: add silent install/update lifecycle for managed CLI tools
Expand tool version detection to all six managed apps (including Hermes
via PyPI), and add a run_tool_lifecycle_action command that installs or
updates CLI tools silently: it captures the subprocess output and blocks
until the command actually finishes instead of popping a terminal window
(Windows uses CREATE_NO_WINDOW). On failure the last lines of stderr are
returned so the UI can surface a useful message.

Also restores the Windows version-detection path by gating try_get_version
behind cfg(not(windows)) so it no longer risks triggering the App
Execution Alias / protocol handler that previously disabled Windows.
2026-05-25 22:20:34 +08:00
Jason c12d20efd0 refactor(proxy): replace panic-prone unwrap/expect with safe patterns
Harden the proxy module against panics by removing optimistic
unwrap()/expect() calls in favor of pattern matching and graceful
fallbacks:

- copilot_optimizer/cache_injector: bind Value::Array/String directly
  instead of is_array()+as_array().unwrap(); use is_none_or and in-place
  string mutation
- hyper_client: gate the raw-write path with if-let + filter instead of
  has_cases + unwrap()
- gemini_shadow: recover poisoned RwLock via into_inner() rather than
  panicking, with warn logging
- streaming_codex_chat: replace expect("tool state exists") with
  let-else (return/continue)
- merge_tool_results: early-return when messages is absent
- sse: fall back to from_utf8_lossy on the UTF-8 boundary slice

No behavior change on the happy path; all proxy tests pass.
2026-05-25 22:20:34 +08:00
Jason 279b9eabde test: align stale tests with merged Codex preset and bucket changes
CI on main was red because two tests did not follow intentional changes
that were already merged into the codebase:

- codexChatProviderPresets.test.ts still expected the "Kimi For Coding"
  preset, which was removed in 16c3ef3f. Drop the corresponding entry
  from the expected presets map.
- import_export_sync.rs still asserted the legacy per-provider
  model_provider id ("rightcode"), but 9fac15b8 unified Codex
  third-party providers into the stable "custom" history bucket. Mirror
  the assertion update already applied to provider_service.rs.

No production code changed; both fixes only update test expectations.
2026-05-25 22:20:34 +08:00
Jason f9db9913a0 fix: coerce empty tool-call arguments to {} in Codex Chat transform
No-argument tool calls produced empty argument strings that passed
through both the streaming response path and the request transform
verbatim. Strict OpenAI-compatible upstreams (e.g. Minimax) reject
`arguments: ""` with a 400 "invalid function arguments json string",
while lenient ones (OpenAI, Kimi) silently treat it as an empty object.

Add canonicalize_tool_arguments / canonicalize_tool_arguments_str helpers
that coerce empty/whitespace arguments to "{}" and apply them at the four
tool-call argument sites (streaming finalize + three request/response
transform paths). Leave function_call_output content untouched, where an
empty string is valid.
2026-05-25 22:20:34 +08:00
Jason 11edc96a15 docs: document Codex Chat reasoning auto-detection
Add a "Reasoning Auto-Detection" subsection to the Codex local-routing
manual (zh/en/ja) with the provider capability matrix, and record the
feature plus the streaming-usage and tool-call reasoning backfill fixes
in the changelog. Drop the removed Kimi For Coding preset from the
changelog's Codex Chat preset list.
2026-05-25 22:20:34 +08:00
Jason 44d9aabbf3 feat: adaptive reasoning detection for Codex Chat providers
Auto-detect each Chat-routed Codex provider's reasoning interface from
its name, base URL, and model, then inject the matching thinking
parameter without manual configuration:

- Platform-first inference (OpenRouter, SiliconFlow) overrides model
  rules, since the same model exposes different reasoning controls
  depending on the hosting platform.
- Effort tiers are forwarded only to providers that support them
  (DeepSeek, OpenRouter, and StepFun's step-3.5-flash-2603); on/off-only
  providers (Kimi, GLM, Qwen, MiniMax, MiMo, SiliconFlow) drop the level
  instead of sending a field the upstream rejects.
- OpenRouter uses the native reasoning:{effort} object, clamps max to
  xhigh (its enum has no max), and forwards an explicit effort:"none" so
  reasoning can be turned off.
- StepFun falls back to inference so per-model effort support is honored
  (the static preset would have forced effort on step-3.5-flash too).

Includes the Codex provider-form reasoning controls, i18n strings
(zh/en/ja), and response-side reasoning extraction.
2026-05-25 22:20:33 +08:00
Jason 5048ed632d fix: inject stream_options.include_usage for Codex Chat streaming
Responses-to-Chat conversion did not set stream_options.include_usage,
so OpenAI-compatible upstreams (kimi/MiniMax, etc.) omitted the trailing
usage chunk in streaming mode. This caused token/cost/cache stats to be
recorded as zero for third-party streaming requests routed through the
Codex Chat path.

Inject include_usage when the request is streaming, merging into any
client-provided stream_options instead of overwriting it. Add tests for
the streaming, non-streaming, and merge cases.
2026-05-25 22:20:33 +08:00
Jason 7410494645 feat: remove Kimi For Coding preset from Codex
The Kimi For Coding preset pins users to a single coding-only model
(kimi-for-coding), restricting model selection. Drop it from the Codex
presets and trim the corresponding row in the trilingual user manual.
The general Kimi preset (Moonshot platform) is kept, and presets for
other apps are unchanged.
2026-05-25 22:20:33 +08:00
Jason b710c6549e fix: backfill placeholder reasoning_content for bare tool-call messages
Thinking models like kimi/Moonshot and DeepSeek reject any assistant
message carrying tool_calls without a non-empty reasoning_content. When
cross-turn history recovery misses (proxy restart drops the in-memory
cache, ambiguous call_id, or a turn produced no reasoning upstream), the
converted assistant message has none and the whole request fails with
'reasoning_content is missing in assistant tool call message'.

Add a final-stage backfill that runs after all input items are
processed, so genuine trailing reasoning items still attach first and a
placeholder is only injected when none remains. Mirrors the placeholder
behavior in transform::anthropic_to_openai_with_reasoning_content.
2026-05-25 22:20:33 +08:00
Jason 184cbcdc47 fix: reclassify ClaudeAPI as aggregator to re-enable model test
ClaudeAPI supports the health/stream check, but the third_party
category triggers the isClaudeThirdParty gate in ProviderCard that
disables the model test button for third-party Claude providers.
Recategorizing as aggregator restores the test action; the partner
star is unaffected since it is driven by isPartner, not category.

Applied to both the Claude Code and Claude Desktop presets.
2026-05-25 22:20:33 +08:00
Jason 04af87bc7b docs: document Codex Chat provider support in changelog and manual
Backfill the empty [Unreleased] CHANGELOG section with the Codex Chat
Completions feature (Chat-to-Responses bridge, 23 third-party presets,
model mapping table, Stream Check routing, error-envelope conversion,
"custom" history bucket) plus the community fixes landed since v3.15.0.

Update the zh/en/ja user manual: split the Codex preset tables by
upstream protocol (native Responses vs Chat Completions), add a "Codex
Local Routing and Model Mapping" section covering the Needs Local
Routing toggle and the model catalog, and note Chat-format probing in
the Stream Check guide. Manual wording matches the live UI strings.
2026-05-25 22:20:33 +08:00
Jason ead9e22b21 feat: convert Codex Chat error responses to Responses envelope
The Codex Chat-to-Responses bridge already rewrites successful upstream
responses to the Responses shape, but the error branch in
handle_codex_chat_to_responses_transform passed Chat-shaped error bodies
through untouched (MiniMax base_resp, raw OpenAI Chat error, text/plain
"Unauthorized" pages, etc.), leaving Codex clients unable to recognize the
error.

Add chat_error_to_response_error in transform_codex_chat to regularize all
upstream error shapes into the standard {error: {message, type, code, param}}
envelope, then wire it through a new handle_codex_chat_error_response that
preserves the original HTTP status code. Non-JSON error bodies (HTML, plain
text) are wrapped as Value::String and truncated to 1KB at a UTF-8 char
boundary to keep diagnostic context without flooding the response.

Also fix a pre-existing append-vs-insert pitfall in three rebuilt-body
branches (Claude transform, Codex Chat normal, Codex Chat error): http
Builder::header is append, so leaking the upstream Content-Type produced
two Content-Type headers when the rewritten body was JSON. Remove the
upstream value before writing application/json.
2026-05-25 22:20:33 +08:00
Jason 72bc912e0d feat: route Codex Chat providers through Stream Check
Codex Chat providers (apiFormat=openai_chat, e.g. DeepSeek, MiniMax, Kimi)
were incorrectly probed via /v1/responses by Stream Check, which the upstream
rejects. Detect chat routing via codex_provider_uses_chat_completions and
issue the probe against /chat/completions with a Chat-shaped body.

Also align URL fallback order with the production CodexAdapter::build_url:
origin-only base URLs (https://api.deepseek.com) must hit /v1/<endpoint>
first; bare /<endpoint> only as a fallback. The previous order made any
non-404 error on the bare path (401/400/405) flag the provider as down even
though /v1/<endpoint> would have succeeded.

- Lift origin-only detection into proxy::providers::is_origin_only_url so
  both build_url and Stream Check share a single source of truth.
- Collapse resolve_codex_stream_urls and resolve_codex_chat_stream_urls into
  a generic resolve_codex_endpoint_urls(base_url, is_full_url, endpoint),
  which also gives the Responses path a symmetric "full endpoint without
  is_full_url flag" fallback for free.
- Restrict reasoning_effort propagation in the Chat branch to OpenAI o-series
  models, mirroring transform_codex_chat's runtime check.
2026-05-25 22:20:33 +08:00
Jason 955904f719 refactor: rewrite Codex local routing toggle hints for clarity
Reframe OFF/ON hints as action guidance (when to enable) rather than
scenario descriptions, mirroring the Claude Desktop model mapping copy
style. Synced across zh/en/ja locales and the component-level
defaultValue fallback. The switch label "Needs Local Routing" is kept
unchanged to preserve the routing-layer semantics specific to Codex.
2026-05-25 22:20:33 +08:00
Jason 9d35709805 fix: collapse mid-stream system messages in Codex Responses to Chat conversion
MiniMax's OpenAI-compatible chat endpoint strict-rejects any non-leading
role=system message with "invalid params, chat content has invalid message
role: system (2013)". The Codex client uses role=developer (and occasionally
role=system) to inject collaboration_mode / permissions / skills blocks
mid-conversation, and responses_role_to_chat_role maps both to chat's
system role. The converted messages array therefore frequently contained
system entries past index 0, which DeepSeek and OpenAI tolerate but MiniMax
flags as 2013.

Collapse all system messages into a single leading system message before
returning the chat request. The rewrite preserves every system fragment
(joined by "\n\n" in original order) and leaves non-system messages
untouched, so it is lossless for permissive backends as well.

- Add collapse_system_messages_to_head in transform_codex_chat.rs.
- Run it on the messages vector at the end of responses_to_chat_completions
  before serializing.
- Cover the new path with two unit tests: one repros the MiniMax-shaped
  input (developer items between users) and asserts no system role past
  index 0; the other verifies non-system order is preserved and content
  is joined with "\n\n".
2026-05-25 22:20:33 +08:00
Jason f2935a3db9 feat: add Chat Completions routing for 22 Codex third-party presets
Enable openai_chat routing with explicit model catalogs across the major
Chinese/Asian providers (DeepSeek, Zhipu GLM, Kimi, MiniMax, Baidu Qianfan,
Bailian, StepFun, Volcengine Agent Plan, BytePlus, DouBaoSeed, ModelScope,
Longcat, BaiLing, Xiaomi MiMo, SiliconFlow, Novita AI, Nvidia, etc.). Each
preset declares its context window so the UI can size catalog rows when the
preset is picked.

Also lands two consistency fixes uncovered along the way:
- Include setCodexCatalogModels in resetCodexConfig's useCallback deps to
  match the new third parameter it consumes.
- Realign TheRouter Codex test to the "custom" model_provider bucket
  established by the recent third-party unification; the previous assertion
  predated that refactor and had been failing on HEAD.
2026-05-25 22:20:33 +08:00
Jason ad8bdf16ae fix: preserve Codex model catalog on live read of active provider
Editing the currently active Codex provider triggered `read_live_settings`,
which returned only { auth, config }, omitting `modelCatalog`. The form's
mapping table then initialized to empty, and a subsequent save wiped the
DB's `modelCatalog` field — silently destroying user-configured model
mappings after every CC Switch restart.

The mappings already live on disk as a projection in
`~/.codex/cc-switch-model-catalog.json` (pointed at by `config.toml`'s
`model_catalog_json`). Reverse-parse that file so live reads return the
same shape the save path writes.

- Add `read_codex_model_catalog_simplified_from_live` to recover
  `{ model, displayName?, contextWindow? }` entries from the catalog file.
- Skip user-managed external catalogs (filename != cc-switch-model-catalog.json)
  so we don't downgrade their richer structure to the simplified table.
- Squash display_name == slug and context_window == default (config's
  `model_context_window`, or 128_000 fallback) so blank inputs round-trip
  back to blank instead of materializing fallback values in the UI.
- Collapse all failure modes (missing file, parse error, no matching
  field) to Ok(None) so the editor stays openable when the projection
  file is absent or corrupt.
- Wire the new function into `read_live_settings`'s Codex branch.
- Cover the new pure helpers with 7 unit tests in codex_config::tests.
2026-05-25 22:20:33 +08:00
Jason b44f83f7c5 feat: unify Codex third-party providers into stable "custom" history bucket
Codex filters resume history by `model_provider`, so switching between
provider-specific ids like `rightcode` and `aihubmix` made past sessions
appear to vanish. Collapse all third-party providers into a single
stable bucket so cross-switch history stays visible.

- Normalize live `model_provider` to "custom" on every Codex write
  (reserved built-in ids like openai/ollama are preserved).
- Add device-level one-shot migration that rewrites historical JSONL
  session files and the `state_5.sqlite` threads table from legacy
  provider ids into the "custom" bucket. Backs up originals under
  `~/.cc-switch/backups/codex-history-provider-migration-v1/` and uses
  the SQLite Backup API for the state DB.
- Record completion in `settings.json` under `localMigrations` so the
  migration is strictly idempotent across launches.
- Update Codex provider preset templates to emit `model_provider = "custom"`
  out of the box.
2026-05-25 22:20:33 +08:00
Jason 2a4651a21e feat: preserve user-selected catalog model in Codex Chat requests
When Codex client sends a model from the catalog (e.g., user selected via /model),
preserve that choice instead of always replacing with config.toml's default model.

- Check if request model exists in modelCatalog before falling back to config model
- Remove CODEX_CHAT_CLIENT_MODEL constant (no longer needed)
- Add test coverage for catalog model preservation
2026-05-25 22:20:33 +08:00
Jason 9b9578206b fix: prevent infinite render loop in Codex model catalog
Break bidirectional sync cycle between catalogRows (child) and catalogModels (parent):
- Remove catalogModels from child→parent effect dependencies
- Track last sent data in ref to avoid redundant callbacks
- Sync ref when parent pushes new data to prevent false positives

Fixes severe UI jittering when adding/editing catalog entries.
2026-05-25 22:20:33 +08:00
Jason 791ced0034 fix: Codex model catalog WYSIWYG and config consolidation
- Remove mergeCodexDefaultCatalogModelForSave implicit injection (P1)
  The model mapping table is now the single source of truth; no hidden
  entries are prepended on save.

- Sync first catalog row model into config.toml on save
  Ensures Codex default request model matches the table's first entry
  instead of retaining a stale template value.

- Remove API Format selector from CodexFormFields (P3)
  wire_api is always 'responses'; the selector confused users into
  thinking they were changing the upstream protocol. Only the 'Needs
  Local Routing' toggle remains.

- Add restart hint to model mapping i18n text (P2)
  model_catalog_json is loaded at Codex startup; users are now informed
  that a restart is needed after changes.

- Unify write_codex_live_with_catalog helper (P4)
  Replaces three scattered prepare+write call sites in config.rs,
  provider/live.rs, and proxy.rs with a single entry point.

- Clean up useCodexConfigState dead state (P3 follow-up)
  Remove codexModelName, codexContextWindow, codexAutoCompactLimit and
  their handlers/effects since no component consumes them after the UI
  consolidation.
2026-05-25 22:20:33 +08:00
Jason 90b7f25111 - Restore Codex Chat reasoning fallback
- Add unique call-id fallback when Codex omits or rewrites previous_response_id.

- Keep ambiguous call ids unresolved to avoid cross-request history leaks.

- Cover fallback and ambiguity behavior with regression tests.
2026-05-25 22:20:33 +08:00
Jason 22fbe6f11a - Optimize Codex Chat cache stability
- Stop deriving Codex session/cache identity from `previous_response_id`.
  - Canonicalize parseable JSON string payloads in Chat and Responses tool conversions.
  - Add regression coverage for cache-sensitive conversion behavior.
2026-05-25 22:20:33 +08:00
Jason 74acf1e387 Add Codex Chat-to-Responses bridge
- Add Codex provider API format selection and model mapping for Chat-only upstreams.
- Convert Codex Responses requests to Chat Completions and rebuild Chat responses as Responses output.
- Preserve reasoning_content across non-streaming, streaming, tool calls, and previous_response_id follow-ups.
- Add a bounded Codex Chat history cache for restoring tool calls before tool outputs.
- Cover Chat bridge, compact routing, streaming, and history recovery with focused tests.
2026-05-25 22:20:33 +08:00
狂飙 5315fa284b Update 1.2-installation.md (#2949)
增加 Windows 运行后无提示的修复方法
2026-05-20 15:04:56 +08:00
Jason 00b6cc6809 fix: format providerConfigUtils.ts to pass CI checks 2026-05-19 16:40:19 +08:00
Jason 398f40dacb docs: recommend official Homebrew cask installation
- Remove personal tap requirement from all READMEs (en/zh/ja)
- Update v3.15.0 release notes to highlight official cask availability
- Add celebration banner noting Homebrew official repository inclusion
- Simplify installation to single command: brew install --cask cc-switch
2026-05-19 16:14:56 +08:00
Jason 09f67c1b38 Handle inline thinking in Codex Chat conversion
- Split leading <think> blocks from Chat content into Responses reasoning output.
- Keep assistant text output free of inline thinking tags.
- Support streamed inline thinking blocks before normal text deltas.
- Add regression coverage for MiniMax-style inline thinking responses.
2026-05-19 11:06:12 +08:00
Jason 79d6486e16 Improve Codex Chat reasoning conversion
- Convert Chat reasoning_content and reasoning fields into Responses reasoning output items.
- Emit Responses reasoning summary SSE events for streamed Chat reasoning deltas.
- Preserve output ordering when reasoning, text, and tool calls are streamed together.
- Add regression coverage for data-only Chat SSE errors, multiple tool calls, and compact routing.
2026-05-19 10:33:24 +08:00
Jason 1c82b8a3fa Add Chat Completions routing for Codex providers
- Add a Codex API format selector and routing badge for Chat Completions providers.
- Convert Codex Responses requests to upstream Chat Completions when routing is required.
- Convert Chat Completions JSON and SSE responses back to Responses format.
- Keep generated Codex wire_api values on Responses for Codex compatibility.
- Add i18n labels, provider metadata handling, and focused conversion tests.
2026-05-19 10:23:48 +08:00
Jason 61e68d754c fix(proxy): inject only ANTHROPIC_API_KEY for managed-account Claude takeover
- Provider: add uses_managed_account_auth / is_github_copilot helpers
  to identify managed-account providers (GitHub Copilot / Codex OAuth)
- ProxyService: choose auth policy by provider type when taking over
  Claude Live config. Managed accounts drop token env keys and write
  only the ANTHROPIC_API_KEY placeholder; other providers keep the
  existing ANTHROPIC_AUTH_TOKEN fallback behavior
- Forwarder: add outbound guard that refuses to send the PROXY_MANAGED
  placeholder upstream to *.githubcopilot.com and chatgpt.com
  /backend-api/codex
- Add unit tests covering detection, injection, and the outbound guard
2026-05-18 22:46:18 +08:00
Jason 76b4c8b509 chore: remove LionCC sponsor and presets
- Remove LionCC sponsor entry from all README files (en/zh/ja)
- Remove LionCCAPI presets from all provider configs
- Remove lionccapi i18n keys from all locales
- Keep lioncc.png icon file as requested
2026-05-18 16:59:13 +08:00
Jason ddde7f13b3 - docs: update user manual for v3.15.0
- Sync zh/en/ja manuals with Claude Desktop and Hermes support

- Update install requirements, official channels, and release asset guidance

- Document Usage Hero, Codex OAuth live models, Save Anyway, Hermes sessions, and Warp launch

- Correct tray and app-scope descriptions to match current implementation
2026-05-18 16:59:13 +08:00
mrzhao c9efec294b fix(skills): install correct skill from skills.sh search results (#2784)
* fix(skills): install correct skill from skills.sh search results

When multiple skills share the same directory name across different repos,
SkillCard was passing directory to onInstall/onUninstall, causing handleInstall
to always match the first result. Switch to using the unique key field
(directory:repoOwner:repoName) for precise identification.

* test(skills): add regression test for skills.sh install by key

Verifies that clicking install on the second card when two skills share
the same directory name correctly installs the second skill, not the first.

---------

Co-authored-by: mrzhao <mrzhao@iflytek.com>
2026-05-18 11:45:54 +08:00
Roger Deng 0977dcd1c1 fix skill sync copy fallback (#2791) 2026-05-18 11:40:45 +08:00
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
luw2007 5ae9c2605d fix(terminal): Ghostty opens clean window instead of cloning existing tabs (#2801)
When Ghostty is already running, `open -a` silently ignores `--args`,
and `open -na` clones all existing tabs into the new instance.

Add a dedicated `launch_macos_ghostty` that uses
`--quit-after-last-window-closed=true` and `-e bash <script>` to spawn
a single clean window running claude.

Also change `launch_macos_open_app` from `open -a` to `open -na` so
other terminals (Alacritty/Kitty/WezTerm/Kaku) correctly open a new
window when already running.

Closes #2798
2026-05-18 11:37:27 +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
Tiancrimson 5c79cf64a4 fix(gemini-native): resolve functionResponse.name and replay thought_signature for synthesized tool call IDs (#2814)
* fix(gemini-native): resolve functionResponse.name and thought_signature replay for synthesized tool call IDs

Two related bugs in the Gemini Native format conversion layer:

1. **functionResponse.name resolution** (422 error): When Gemini's parallel
   function calls omit the id field, cc-switch synthesizes gemini_synth_*
   IDs. These are stored in the shadow store but can be lost in long sessions,
   causing subsequent tool_result blocks to fail. Fix: pre-scan all assistant
   messages in the request body to seed the tool_name_by_id map, and add a
   last-resort fallback that scans the current content array for matching
   tool_use blocks.

2. **thought_signature replay** (400 error): The Anthropic Messages format
   strips thoughtSignature from tool_use blocks, but Gemini requires it on
   every functionCall in multi-turn tool-use exchanges. Fix: build a
   thought_signature_by_id map from shadow turns and attach thoughtSignature
   when converting tool_use back to functionCall.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* style: run cargo fmt on transform_gemini.rs

---------

Co-authored-by: Tiancrimson <tiancrimson@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-05-18 10:25:35 +08:00
LaoYueHanNi bbce75fcda fix(session): 修复session log模式下子Agent token统计遗漏 (#2821)
* fix(session): 修复session log模式下子Agent token统计遗漏

collect_jsonl_files() 只扫描了两层目录,遗漏了子Agent的JSONL日志文件,
导致子Agent的独立token使用数据完全未统计到session费用中。
(仅影响session log模式,proxy代理模式不受影响)

* refactor(session): optimize collect_jsonl_files logic

- Replace two independent if statements with if-else for mutually exclusive conditions
- Remove unnecessary clone() when pushing file paths
- Add clarifying comments for main session vs subagent files
- Apply cargo fmt for consistent formatting

Performance improvement: Eliminates redundant clone() operations when
processing .jsonl files, as a path cannot be both a file and a directory.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2026-05-18 10:00:57 +08:00
iamryan ed33990b9c fix-codex-mise-detection (#2822) 2026-05-18 09:38:08 +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 4f0f103a8a Add Claude Desktop user guide docs
- Add the Claude Desktop provider guide in English, Chinese, and Japanese.
- Add localized screenshots for import, provider setup, model mapping, and local routing.
- Link the guide from the v3.15.0 release notes and user manual indexes.
2026-05-16 20:18:49 +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 6172bfd549 docs(release-notes): soften imposter warning wording in en/ja notes 2026-05-16 13:26:53 +08:00
Jason 1232b49b74 docs(release-notes): soften imposter warning wording in zh notes 2026-05-16 13:25:09 +08:00
Jason 3640a4e27d docs(release-notes): remove emoji from imposter site warning 2026-05-16 13:21:44 +08:00
Jason fed892d307 docs(release-notes): add imposter site warning to v3.15.0 notes 2026-05-16 13:19:33 +08:00
Jason 9e3f168903 chore(release): bump version to 3.15.0 v3.15.0 2026-05-16 11:21:18 +08:00
Jason 9e6a7a0d81 - Fix proxy test helper clippy warning
- Mark `should_force_identity_encoding` as test-only.

- Keep runtime forwarding behavior unchanged.

- Verified with local CI checks and no-bundle Tauri build.
2026-05-15 23:45:26 +08:00