Update CHANGELOG.md with full v3.12.3 entry, create release notes in
three languages (en/zh/ja), bump macOS minimumSystemVersion from 10.15
to 12.0 (Monterey) to match actual runtime requirements, and update
README version badges and links.
Introduce list/restore/delete commands for skill backups created during
uninstall. Restore copies files back to SSOT, saves the DB record, and
syncs to the current app with rollback on failure. Delete removes the
backup directory after a confirmation dialog. ConfirmDialog gains a
configurable zIndex prop to support nested dialog stacking.
Create a local backup under ~/.cc-switch/skill-backups/ before removing
skill directories. The backup includes all skill files and a meta.json
with original skill metadata. Old backups are pruned to keep at most 20.
The backup path is returned to the frontend and shown in the success
toast. Bump version to 3.12.3.
Non-streaming requests were forced to use `Accept-Encoding: identity`,
preventing upstream response compression and increasing bandwidth usage.
Now only streaming requests conservatively keep `identity` to avoid
decompression errors on interrupted SSE streams. Non-streaming requests
let reqwest auto-negotiate gzip and transparently decompress responses.
Responses API uses max_output_tokens for all models including o-series.
The o-series max_completion_tokens fix should only apply to Chat Completions API.
* fix(proxy): use max_completion_tokens for o1/o3 series models
When converting Anthropic requests to OpenAI format for o1/o3 series
models (like o1-mini, o3-mini), use max_completion_tokens instead of
max_tokens to avoid unsupported_parameter errors.
Fixes#1448
* fix: revert incorrect o-series max_completion_tokens in Responses API path
Responses API uses max_output_tokens for all models including o-series.
The o-series max_completion_tokens fix should only apply to Chat Completions API.
---------
Co-authored-by: Hajen Teowideo <hajen.teowideo@example.com>
Co-authored-by: Jason Young <44939412+farion1231@users.noreply.github.com>
Co-authored-by: Jason <farion1231@gmail.com>
Resolve the active `claude` command from PATH and apply an equal-length
byte patch to remove the domain whitelist check. Backups are stored in
~/.cc-switch/toolsearch-backups/ (SHA-256 of path) so they survive
Claude Code version upgrades. The patch auto-reapplies on app startup
when the setting is enabled.
Frontend checks PatchResult.success and rolls back the setting on failure.
Skills import previously inferred app enablement from filesystem presence,
causing incorrect multi-app activation when the same skill directory existed
under multiple app paths. Now the frontend submits explicit app selections
via ImportSkillSelection, and schema migration preserves a snapshot of
legacy app mappings to avoid lossy reconstruction.
Also adds reconciliation to sync_to_app (removes disabled/orphaned symlinks)
and MCP sync_all_enabled (removes disabled servers from live config).
When proxy takeover is active, update_live_backup_from_provider rebuilds the Codex restore snapshot from the current provider and common-config state. We were then replacing the new mcp_servers table with the previous backup's table wholesale, which meant stopping takeover could restore stale MCP entries and silently discard MCP changes made through provider/common-config updates.
Change the backup preservation step to merge MCP entries by server id instead of replacing the entire table. New provider/common-config MCP definitions now win on conflict, while backup-only servers are retained so live-only MCP state still survives a hot-switch.
Add regression coverage for the existing preservation case and for the conflict case where both the old backup and the new provider define the same MCP server.
Rewrite setCodexBaseUrl/extractCodexBaseUrl to understand TOML section
boundaries, ensuring base_url is written into the correct
[model_providers.<name>] section instead of being appended to file end.
- Add section-aware TOML helpers in providerConfigUtils.ts
- Extract shared update_codex_toml_field/remove_codex_toml_base_url_if
in codex_config.rs, deduplicate proxy.rs TOML editing logic
- Replace scattered inline base_url regexes with extractCodexBaseUrl()
- Add comprehensive tests for both Rust and TypeScript implementations
- Make sync_current_provider_for_app takeover-aware: update restore
backup instead of overwriting live config when proxy is active
- Introduce explicit "cleared" flag for common config snippets to
prevent auto-extraction from resurrecting user-cleared snippets
- Reorder startup: extract snippets from clean live files before
restoring proxy takeover state
- Add one-time migration flag to skip legacy commonConfigEnabled
migration on subsequent startups
- Add regression tests for takeover backup preservation, explicit
clear semantics, and migration flag roundtrip
Update takeover backup generation to rebuild effective provider settings with common config applied before saving restore snapshots.
Keep Codex mcp_servers entries when hot-switching providers under takeover so restore does not drop live-only MCP config.
Migrate legacy providers with inferred common-config usage to explicit commonConfigEnabled=true markers during startup and default imports, and cover the new behavior with proxy and provider regression tests.
Split LOCAL_ONLY_TABLES into SYNC_SKIP_TABLES (export) and
SYNC_PRESERVE_TABLES (import). provider_health is skipped on export
but no longer restored on import, since it has a foreign key on
providers(id, app_type) that may not match the remote dataset.
Health data is ephemeral and rebuilds automatically at runtime.
Add a switch in the OpenClaw provider form to optionally send a browser
User-Agent header. The toggle defaults to off — only providers that
explicitly include headers in their preset or config will have it enabled.
Remove the previous auto-injection logic that force-added User-Agent on
every preset load and new provider creation.
Add enableFailoverToggle setting to control failover toggle visibility
on the main page, decoupled from proxy takeover state. First-time
enable shows a ConfirmDialog (same pattern as proxy toggle). The toggle
row is placed in the Auto Failover accordion section in settings.
Common config snippets are now dynamically overlaid when writing live
files, rather than being pre-merged into provider snapshots at edit time.
This ensures that updating a snippet immediately takes effect for the
current provider and automatically propagates to other providers on
their next switch.
Key changes:
- Add write_live_with_common_config() overlay pipeline
- Strip common config from live before backfilling provider snapshots
- Normalize provider snapshots on save to keep them snippet-free
- Add explicit commonConfigEnabled flag in ProviderMeta (Option<bool>)
- Migrate legacy providers on snippet save (infer flag from subset check)
- Add Codex TOML snippet validation in set_common_config_snippet
- Stabilize onConfigChange callbacks with useCallback in ProviderForm
Separate protocol version from database compatibility version in WebDAV
sync paths. Upload writes to v2/db-v6/<profile>, download falls back to
legacy v2/<profile> when current path has no data. Extend manifest with
optional dbCompatVersion field and add legacy layout detection to UI.
- Add usage_daily_rollups table (schema v6) to aggregate proxy request
logs into daily summaries, reducing query overhead for statistics
- Add rollup_and_prune DAO that aggregates old detail logs (>N days)
into rollup rows and deletes the originals
- Update all usage stats queries to UNION detail logs with rollup data
- Introduce incremental auto-vacuum for SQLite, with startup and
periodic cleanup of old stream_check_logs and request log rollups
- Split backup export/import into full vs sync variants: WebDAV sync
now skips local-only table data (proxy_request_logs,
stream_check_logs, provider_health, proxy_live_backup,
usage_daily_rollups) while preserving them on import
- Add enable_logging guard to skip request log writes when disabled
- Apply cargo fmt formatting fixes across multiple modules
Rewrite tool call handling in streaming format conversion to properly
track multiple concurrent tool blocks with independent Anthropic content
indices. Fix block interleaving (thinking/text/tool_use) with correct
content_block_start/stop events, buffer tool arguments until both id and
name are available, and add tool result message conversion in transform.
- Extract shared map_responses_stop_reason and build_anthropic_usage_from_responses into transform_responses.rs as pub(crate)
- Align cache token extraction priority: OpenAI nested details as fallback, direct Anthropic fields as override
- Extract resolve_content_index helper to eliminate 3x copy-paste in streaming_responses.rs
- Add streaming reasoning/thinking event handlers (response.reasoning.delta/done)
- Add explanatory comment to transform_response heuristic detection
- Add openai_responses to api_format doc comment and needs_transform test
- Add explicit no-op match arms for lifecycle events
- Add promptCacheKey to TS ProviderMeta type
- Update toast i18n key to be generic for both OpenAI formats (zh/en/ja)
Support Anthropic ↔ OpenAI Responses API format conversion alongside existing
Chat Completions conversion. The Responses API uses a flat input/output structure
with lifted function_call/function_call_output items and named SSE lifecycle events.
Show an informational dialog when users first click the health check
button, explaining its limitations (OAuth providers, relay services,
Bedrock). The dialog persists the confirmation in settings so it only
appears once per device.
Stream Check always used Anthropic Messages API format, causing false
failures for providers with api_format="openai_chat" (e.g. NVIDIA).
Now detects api_format from provider meta/settings_config and uses
the correct endpoint (/v1/chat/completions) and headers accordingly.
During app startup, iterate all app types and extract non-provider-specific
config fields from live configuration files into the database. This runs
only when no snippet exists yet for a given app type, enabling incremental
extraction as new apps are configured.
Revert the partial key-field merging refactoring introduced in 992dda5c,
along with two dependent commits (24fa8a18, 87604b18) that referenced
the now-removed ClaudeQuickToggles component.
The whitelist-based partial merge approach had critical issues:
- Non-whitelisted custom fields were lost during provider switching
- Backfill permanently stripped non-key fields from the database
- Whitelist required constant maintenance to track upstream changes
This restores the proven "full config overwrite + Common Config Snippet"
architecture where each provider stores its complete configuration and
shared settings are managed via a separate snippet mechanism.
Reverted commits:
- 24fa8a18: context-aware JSON editor hint + hide quick toggles
- 87604b18: hide ClaudeQuickToggles when creating
- 992dda5c: partial key-field merging refactoring
Restored:
- Full config snapshot write (write_live_snapshot) for Claude/Codex/Gemini
- Full config backfill (settings_config = live_config)
- Common Config Snippet UI and backend commands
- 6 frontend components/hooks for common config editing
- configApi barrel export and DB snippet methods
Removed:
- ClaudeQuickToggles component
- write_live_partial / backfill_key_fields / patch_claude_live
- All KEY_FIELDS constants
Previously OpenCode and OpenClaw auto-imported providers from live config
on app startup, which could confuse users. Now they follow the same
pattern as Claude/Codex/Gemini: manual import via the empty state button.
- Update version numbers in package.json, Cargo.toml, tauri.conf.json
- Add CHANGELOG.md entry for v3.11.0
- Add trilingual release notes (zh/en/ja)
- Update user manual version info