Commit Graph

1404 Commits

Author SHA1 Message Date
Jason 33f5d56afd fix: move skill settings above window settings in general tab 2026-04-09 16:49:13 +08:00
Jason 8cfce8abfc feat: add skill storage location toggle between CC Switch and ~/.agents/skills
Allow users to choose between storing skills in CC Switch's managed
directory (~/.cc-switch/skills/) or the Agent Skills open standard
directory (~/.agents/skills/). Includes migration logic that safely
moves files before updating settings, with confirmation dialog for
non-empty installations.
2026-04-09 16:49:13 +08:00
Jason 6d220b2528 fix: animate "Update All" button sliding in from the left of "Check Updates"
Use max-width + opacity CSS transition so the button smoothly expands
into view instead of popping in abruptly.
2026-04-09 16:49:13 +08:00
Jason b7e99014c9 feat: add "Update All" button for batch skill updates
Show an "Update All (N)" button next to "Check Updates" when updates
are available. Sequentially updates each skill and reports results.
2026-04-09 16:49:13 +08:00
Jason e3179ad9e4 feat: add skill update detection via SHA-256 content hashing
- Add content_hash and updated_at fields to skills table (DB migration v6→v7)
- Compute directory content hash on install/import/restore for version tracking
- Add check_updates command: downloads repos, compares hashes, returns update list
- Add update_skill command: backs up old files, re-downloads and replaces SSOT
- Backfill content_hash for existing skills on first update check
- Add "Check Updates" button and per-skill update badge/button in UnifiedSkillsPanel
- Add i18n keys for zh/en/ja
2026-04-09 16:49:13 +08:00
Jason 46488ecd93 fix: set default auto-query interval to 5min and fix number input clearing
- Change default autoQueryInterval from 0 (disabled) to 5 minutes for
  new usage scripts (Token Plan, Balance, and general templates)
- Fix controlled number inputs (timeout & interval) that couldn't be
  cleared: defer validation to onBlur so users can delete and retype
2026-04-09 16:49:13 +08:00
Jason 9192b6f988 fix: align usage display across provider cards by always rendering action buttons
Test and ConfigureUsage buttons are now always rendered instead of
conditionally, with a disabled style for providers that don't support
them (e.g. official subscriptions). This ensures consistent button
container width so the usage display aligns uniformly across all cards.
2026-04-09 16:49:13 +08:00
Jason f1fb3351c1 feat: add official balance query for DeepSeek, StepFun, SiliconFlow, OpenRouter, Novita AI
Add a new "Official" (官方) template type in the usage query panel that
queries account balance via each provider's native API endpoint.
Follows the same zero-script pattern as Token Plan — Rust handles the
HTTP call, frontend auto-detects the provider from base URL.

Supported providers and endpoints:
- DeepSeek: GET /user/balance
- StepFun: GET /v1/accounts
- SiliconFlow: GET /v1/user/info (cn + com)
- OpenRouter: GET /api/v1/credits
- Novita AI: GET /v3/user/balance
2026-04-09 16:49:13 +08:00
Satoru 24555275bb fix: add padding to toolbar container to prevent add button shadow clipping (#1951)
The orange add button's circular shadow appeared square because the
parent overflow-x-hidden container was clipping it at the edges.
2026-04-08 21:17:19 +08:00
Cod1ng dc4524e960 fix: handle UTF-8 multi-byte characters split across stream chunk boundaries (#1923)
* fix: handle UTF-8 multi-byte characters split across stream chunk boundaries

Replace String::from_utf8_lossy with append_utf8_safe in all four SSE
streaming paths. When a multi-byte UTF-8 character (e.g. Chinese, emoji)
is split across TCP chunk boundaries, from_utf8_lossy silently replaces
the incomplete halves with U+FFFD (�). This caused intermittent garbled
output in Claude Code when using the Copilot reverse proxy, because the
format conversion streams reconstruct SSE events from the corrupted buffer.

The new append_utf8_safe function preserves incomplete trailing bytes in
a remainder buffer and merges them with the next chunk before decoding,
ensuring characters are never split during UTF-8 conversion.

Fixes: intermittent U+FFFD replacement characters in Claude Code output
via Copilot proxy (not reproducible with direct Copilot connections like
opencode because they pass through raw bytes without format conversion).

* style: fix cargo fmt formatting in UTF-8 boundary tests

---------

Co-authored-by: Cod1ng <codingts@gmail.com>
Co-authored-by: encodets <encodets@gmail.com>
2026-04-08 10:02:35 +08:00
Dex Miller 34f16886a2 Normalize fragmented system prompts for strict chat backends (#1942)
Some OpenAI-compatible chat providers reject requests when Claude-side\nsystem fragments arrive as multiple system messages. Normalize the\nconverted OpenAI chat payload so system content becomes a single\nleading system message while leaving the rest of the message stream\nunchanged.\n\nConstraint: Nvidia/Qwen-style chat completions require a single leading system prompt\nRejected: Reorder system messages only | still leaves fragmented system prompts for strict backends\nConfidence: high\nScope-risk: narrow\nReversibility: clean\nDirective: Keep OpenAI chat system prompts normalized unless a provider explicitly requires fragmented system messages\nTested: cargo test proxy::providers::transform --manifest-path src-tauri/Cargo.toml\nNot-tested: Full end-to-end proxy capture against Nvidia upstream in this session\nRelated: #1881
2026-04-08 09:41:20 +08:00
Jason 602c5717b2 fix: gate parse_gemini_keychain_json with cfg(target_os = "macos")
The function is only called from read_gemini_credentials_from_keychain
which is already macOS-only. Without the gate, non-macOS CI fails with
dead-code error due to -D warnings.
2026-04-05 16:04:20 +08:00
Jason 4685e5b597 fix: invert MiniMax usage_count to match 0%→100% convention
usage_count is remaining quota (starts at total, decreases to 0),
not used count. Invert calculation so all providers consistently
show 0% when fresh and 100% when exhausted.
2026-04-05 13:41:52 +08:00
Jason ca6a187745 fix: correct MiniMax quota calculation and improve Token Plan display
- Fix MiniMax usage_count being treated as remaining (was inverted)
- Add MiniMax weekly quota tier extraction
- Remove Zhipu TIME_LIMIT (tools usage), keep only TOKENS_LIMIT
- Improve Kimi parsing with extract_reset_time and parse_f64 helpers
- Reuse TierBadge for Token Plan inline rendering
- Clean up unused i18n keys and debug println
2026-04-05 13:35:54 +08:00
Jason bfdac2a22a feat: add Token Plan quota query for Kimi, Zhipu GLM, and MiniMax
Add a new "Token Plan" template type in the usage query panel that
natively queries quota/usage from Chinese coding plan providers
(Kimi For Coding, Zhipu GLM, MiniMax) without requiring custom scripts.

- Rust backend: new coding_plan service with provider-specific API
  queries (Kimi /v1/usages, Zhipu /api/monitor/usage/quota/limit,
  MiniMax /coding_plan/remains) normalized into UsageResult
- Frontend: Token Plan template in UsageScriptModal with auto-detection
  of provider based on ANTHROPIC_BASE_URL pattern matching
- Follows the same pattern as GitHub Copilot template (dedicated API
  path in queryProviderUsage, no JS script needed)
2026-04-05 11:39:29 +08:00
Jason 8d38f0ee4f fix: allow provider switch without proxy, show warning instead of blocking
Remove the hard block that prevented switching to providers requiring
proxy (OpenAI format, Copilot, full URL mode) when the proxy is not
running. Now the switch proceeds with a warning toast. Also deduplicate
the proxy hint info toast so it doesn't appear alongside the warning.
2026-04-05 09:39:51 +08:00
Jason 159279bf44 feat: restore Copilot preset and auth center tab in settings
Re-enable GitHub Copilot provider preset and the OAuth auth center tab
that were temporarily hidden due to abnormal consumption rates. The
Copilot optimizer introduced in the previous commit addresses the
underlying issue.
2026-04-05 08:34:16 +08:00
Jason 2513687184 feat: add Copilot optimizer to reduce premium interaction consumption
Implement request classification, tool result merging, compact detection,
deterministic request IDs, and warmup downgrade for Copilot proxy.

The root cause was x-initiator being hardcoded to "user", making Copilot
count every API request (including tool callbacks and agent continuations)
as a separate premium interaction. The optimizer dynamically classifies
requests as "user" or "agent" based on message content analysis.

Closes #1813
2026-04-05 08:34:10 +08:00
Jason bcc14bd07d fix: remove hover push animation on provider cards
Keep usage display fixed in place and show action buttons with
a simple opacity fade instead of sliding in and pushing content.
2026-04-04 22:53:20 +08:00
Jason b31bf43e15 fix: hide usage config and health check buttons for official providers
Official providers use built-in subscription quota display instead of
custom usage scripts, and stream check is not applicable. Hide both
action buttons when isOfficialProvider is true.
2026-04-04 22:53:20 +08:00
Jason 98230c3970 feat: add official subscription quota display for Gemini
- Read Gemini OAuth credentials from macOS Keychain (gemini-cli-oauth)
  or legacy file (~/.gemini/oauth_creds.json)
- Auto-refresh expired access tokens using refresh_token (Google OAuth
  tokens expire in ~1h, unlike Claude/Codex)
- Two-step API: loadCodeAssist for project ID, then retrieveUserQuota
  for per-model quota buckets
- Classify models into Pro/Flash/Flash Lite categories, show min
  remaining fraction as utilization percentage
- Extend isOfficialProvider() for Gemini (no API key + no base URL)
- Parameterize expiredHint i18n key with tool name for all three apps
2026-04-04 22:53:20 +08:00
Jason 0200fe79ae feat: add official subscription quota display for Codex
Read Codex OAuth credentials from ~/.codex/auth.json (with macOS
Keychain fallback) and query chatgpt.com/backend-api/wham/usage to
show rate limit utilization on official Codex provider cards. Reuses
the same tier naming (five_hour, seven_day) for frontend i18n compat.
2026-04-04 22:53:20 +08:00
Jason b30f3c27ad feat: display official subscription quota on Claude provider cards
Read Claude OAuth credentials from macOS Keychain (with file fallback)
and query the Anthropic usage API to show quota utilization inline on
official provider cards. Includes compact countdown timer for reset
windows and hides the rarely-used seven_day_sonnet tier in inline mode.
2026-04-04 22:53:20 +08:00
Jason d9c0e4c452 docs: update user manual to v3.12.3 with new features coverage (en/zh/ja)
Add documentation for features introduced since v3.12.0:

New docs:
- 3.4 Session Manager: browse, search, resume, delete sessions
- 3.5 Workspace & Daily Memory: OpenClaw workspace file editing

Updated docs:
- Add Lightweight Mode to interface overview and FAQ
- Add tray submenu structure (providers grouped by app)
- Add API Format selection (Anthropic/OpenAI Chat/OpenAI Responses)
- Add Auto-Fetch Models button documentation
- Add Claude Common Config quick toggles
- Add Codex 1M Context Window toggle
- Add Skill backup/restore lifecycle
- Expand Backup Management panel documentation
- Update WebDAV sync to v2 protocol with dual-layer versioning
- Add OpenCode/OpenClaw to quickstart activation table
- Update README version to v3.12.3

All changes synced across en, zh, and ja locales.
2026-04-04 22:53:20 +08:00
Jason fe525891d4 feat(tray): collapse providers into submenus to prevent menu overflow
Each app type (Claude/Codex/Gemini) now renders as a submenu instead
of flat items, keeping the top-level tray menu compact regardless of
provider count. The submenu label shows the current provider name
(e.g. "Claude · OpenRouter") for at-a-glance visibility.
2026-04-04 22:53:20 +08:00
Jason 84998aa217 feat: differentiate fetch models error messages by failure type
Distinguish between missing API key, missing endpoint, auth failure,
unsupported provider (404/405), and timeout errors instead of showing
a generic failure toast for all cases.
2026-04-04 22:53:20 +08:00
Jason f200feebe4 fix(i18n): move fetchModels keys from copilot to providerForm namespace 2026-04-04 22:53:20 +08:00
Jason 5017002938 feat: add auto-fetch models from provider's /v1/models endpoint
Add ability to fetch available models from third-party aggregation
providers (SiliconFlow, OpenRouter, etc.) via OpenAI-compatible
GET /v1/models endpoint. Users can click "Fetch Models" button in
the provider form, then select models from a dropdown on each
model input field.

- Backend: new model_fetch service + Tauri command (Rust)
- Frontend: ModelInputWithFetch shared component
- Integrated into all 5 app forms (Claude/Codex/Gemini/OpenCode/OpenClaw)
- i18n support for zh/en/ja
2026-04-04 22:53:20 +08:00
Zhou Mengze de49f6fbbe fix(copilot): 修复 GitHub Copilot 认证和代理问题 (#1854)
* fix(copilot): 修复 GitHub Copilot 400 认证错误

问题:使用 GitHub Copilot provider 时报错 400 bad request

根因:与 copilot-api 项目对比发现多处差异

修复内容:
- 更新版本号 0.26.7 到 0.38.2
- 更新 API 版本 2025-04-01 到 2025-10-01
- 添加缺失的关键 headers
- 修正 openai-intent 值
- 添加动态 API endpoint 支持
- 同步更新 stream_check.rs headers

Closes #1777

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: flush stream after write_all in hyper_client proxy

Add explicit flush() calls after write_all() for TLS stream, plain TCP
stream, and CONNECT tunnel requests to ensure buffered data is sent
immediately, preventing connection hangs in Copilot auth header flow.

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

* 修复登录时的剪切板在mac与linux端可能没复制验证码

* fix: flush stream after write_all in hyper_client proxy

Add explicit flush() calls after write_all() for TLS stream, plain TCP
stream, and CONNECT tunnel requests to ensure buffered data is sent
immediately, preventing connection hangs in Copilot auth header flow.

* 修复登录时的剪切板在mac与linux端可能没复制验证码

* 1、修复不同类型的个人商业等不同类型的copilot账号问题
2、将验证码复制改为异步操作

* fix: address PR review comments for Copilot auth                                                      │
│                                                                                                                      │
│ - Fix clipboard blocking by using spawn_blocking for arboard ops                                                     │
│ - Implement dynamic endpoint routing for enterprise Copilot users                                                    │
│ - Add api_endpoints cache cleanup in remove_account() and clear_auth()                                               │
│ - Change API endpoint log level from info to debug                                                                   │
│ - Fix clear_auth() to continue cleanup even if file deletion fails                                                   │
│ - Add 9 unit tests for Copilot detection and api_endpoints cachin

* style: fix cargo fmt formatting

* Fix Copilot dynamic endpoint handling

* fix: restore clear_auth() memory-first cleanup order and fix cache leaks

- Restore clear_auth() to clean memory state before deleting the storage
  file. The previous order (file deletion first) caused a regression where
  users could get stuck in a "cannot log out" state if file removal failed.

- Add missing copilot_models.clear() in clear_auth() — this cache was
  cleaned in remove_account() but never in the full clear path.

- Add endpoint_locks cleanup in both remove_account() and clear_auth()
  to prevent minor in-process memory leaks.

- Update test to assert the correct behavior: memory should be cleaned
  even when file deletion fails.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: 周梦泽 <mengze.zhou@dafeng-tech.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason <farion1231@gmail.com>
2026-04-04 22:52:23 +08:00
Jason Young e4fe2763cd chore(deps): bump actions/cache from 4 to 5 in ci.yml (#1860)
Sync ci.yml with release.yml after dependabot updates.
2026-04-03 16:24:55 +08:00
dependabot[bot] 3e1de466db chore(deps): bump actions/download-artifact from 4 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:29 +08:00
dependabot[bot] 1abe474e75 chore(deps): bump actions/upload-artifact from 4 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:22 +08:00
dependabot[bot] 74d7e86b7a chore(deps): bump pnpm/action-setup from 2 to 5
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 2 to 5.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v5)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:14 +08:00
dependabot[bot] b9297e42f5 chore(deps): bump actions/setup-node from 4 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:40:09 +08:00
dependabot[bot] 7de2db9ee8 chore(deps): bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-03 08:32:17 +08:00
Jason 1b4c3cbcaa ci: add stale bot to auto-close inactive issues after 60 days
- Mark issues as stale after 60 days of inactivity
- Auto-close after 14 more days without response
- Bilingual (zh/en) stale and close messages
- Exempt security and performance labeled issues
- Runs daily at UTC 00:00, processes up to 100 issues per run
- Only affects issues, not pull requests
2026-04-03 00:01:13 +08:00
Jason 2b9b5b0bc3 docs: fix outdated README content and sync across languages
- Fix JA README macOS FAQ still claiming app is unsigned (now code-signed & notarized)
- Update SessionManager description from "Claude Code only" to "all supported apps" (EN/ZH/JA)
- Replace non-existent Flatpak download entry with self-build reference (EN/ZH/JA)
- Add OpenCode and OpenClaw filesystem paths to Flatpak minimal permissions
- Bump user manual version to v3.12.3
2026-04-02 22:38:42 +08:00
Jason 2af38a63b5 docs: point FUNDING.yml to Chinese README sponsor section 2026-04-02 22:22:12 +08:00
Jason 3388cba1dc docs: add sponsor call-to-action to READMEs and fix FUNDING.yml 2026-04-02 22:15:49 +08:00
Jason 8b44d9f54d fix(test): resolve HOME env race condition in parallel tests
- Use get_home_dir() instead of dirs::home_dir() in get_opencode_dir()
  and get_openclaw_dir() to respect CC_SWITCH_TEST_HOME override
- Add CC_SWITCH_TEST_HOME to all TempHome implementations
- Add #[serial] to all with_test_home tests to share serialization
  with other env-mutating tests
- Remove --test-threads=1 workaround from CI
2026-04-02 22:08:12 +08:00
Jason 8cdc07c860 ci: run cargo tests single-threaded to fix HOME env race 2026-04-02 20:38:31 +08:00
Jason 9a44245b73 style: use to_vec() instead of iter().copied().collect() 2026-04-02 17:46:14 +08:00
Jason 1b2885c335 style: use iter().copied() instead of iter().map(|s| *s) 2026-04-02 17:37:04 +08:00
Jason 447a1da7b2 ci: remove nonexistent pnpm lint step 2026-04-02 17:36:26 +08:00
Jason bfe238f301 style: fix formatting issues caught by CI 2026-04-02 17:32:33 +08:00
Jason 0c9a20ca68 ci: add PR and push quality checks workflow 2026-04-02 17:28:01 +08:00
Jason fee8577032 feat: hide GitHub Copilot provider preset and auth tab
Users reported that Copilot support causes excessively fast token
consumption. Temporarily hide the feature by adding a `hidden` field
to ProviderPreset interface and commenting out the auth center tab
in settings. Existing Copilot providers in DB still work via proxy.
2026-04-02 17:15:11 +08:00
Jason bae369b0dc docs: add SUPPORT.md and FUNDING.yml 2026-04-02 16:51:33 +08:00
Jason 6e2baaefa6 docs: add CONTRIBUTING.md, SECURITY.md, and CODE_OF_CONDUCT.md
Add three community health files with bilingual (EN/ZH) support:
- CODE_OF_CONDUCT.md: Contributor Covenant v2.1 with official Chinese translation
- SECURITY.md: security policy pointing to GitHub Security Advisories
- CONTRIBUTING.md: contribution guide with dev setup, code style, PR guidelines,
  i18n rules, and AI-assisted contribution policy
2026-04-02 16:26:26 +08:00
Jason 0001438586 ci: add emoji to issue template names 2026-04-02 15:44:01 +08:00