mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-07-11 02:23:48 +08:00
45edebe8514a4433cb142ac4621b8e52f8e6d5cc
5676 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
45edebe851 |
fix: add manual download option for macOS users with old code signing (#13378)
### What this PR does Before this PR: - macOS users with the old code signing Team ID (Q24M7JR***) cannot auto-update to v1.8.0+ due to signing certificate change - Update request headers lacked app identification information After this PR: - Detects old Team ID on macOS and shows a manual download button directing users to the official website - Adds `App-Name`, `App-Version`, and `OS` headers to update requests for better server analytics - Refactors duplicate headers into a shared `getCommonHeaders()` function ### Why we need it and why it was done in this way The following tradeoffs were made: - Using `codesign -dv` to detect the Team ID at runtime is simple and reliable on macOS The following alternatives were considered: - Checking the app version instead of Team ID, but this wouldn't correctly identify users who haven't updated in a while ### Breaking changes None ### Special notes for your reviewer The old Team ID `Q24M7JR2C4` is hardcoded as a constant. This is intentional since it represents the previous signing certificate that will no longer be used. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A user-guide update was considered and is present (link) or not required - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note Add manual download option for macOS users who cannot auto-update due to code signing certificate change ``` --------- Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
622c39ea64 |
refactor(backup): enhance backup system with legacy backup and path security (#13587)
### What this PR does Before this PR: - Backup system used a complex nested structure that was harder to maintain - No support for legacy backup format (LAN transfer) - Limited path security validation - electron-store config.json was stored in userData root, not included in backups After this PR: - Implements direct backup and restore methods for IndexedDB and Local Storage - Adds legacy backup (LAN transfer) functionality for backward compatibility - Implements startup restoration support - Enhances path security with `resolveAndValidatePath` to prevent directory traversal attacks - Simplifies BackupManager constructor and methods - Adds Joplin and Siyuan icons - Updates backup metadata structure and progress handling - Moves electron-store config.json to userData/Data directory so it's included in backups - Adds automatic migration from legacy config location Fixes # ### Why we need it and why it was done in this way The following tradeoffs were made: - Added path validation overhead for enhanced security - Legacy backup format support increases code complexity but ensures backward compatibility The following alternatives were considered: - Keeping the old backup structure, but it was harder to maintain and extend Links to places where the discussion took place: N/A ### Breaking changes The backup format has been updated to a new version. Existing backups created with older versions will still be supported through the legacy backup functionality. ### Special notes for your reviewer - The `resolveAndValidatePath` utility prevents path traversal attacks by validating that resolved paths stay within expected directories - The BasicDataSettings component was extracted to improve code organization - Tests have been updated to cover the new backup functionality - electron-store config location changed from `userData/config.json` to `userData/Data/config.json` with automatic migration ### Checklist This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR. Approvers are expected to review this list. - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [ ] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note Enhanced backup system with new format (v6), legacy backup support, improved path security, and config.json now included in backups ``` --------- Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
9a58028f74 |
feat(mcp): add whitelist auto-trust for protocol install servers (#13586)
### What this PR does Before this PR: MCP servers installed via protocol (e.g., `cherrystudio://`) always require user confirmation to trust, even for well-known trusted sources like WPS Notes. After this PR: Adds a whitelist mechanism to auto-trust specific MCP server URLs without requiring user confirmation. Currently whitelisted: - `http://127.0.0.1:18930/mcp` (WPS Notes) ### Why we need it and why it was done in this way The following tradeoffs were made: - Hardcoded whitelist vs. user-configurable: Chose hardcoded for security, as allowing user-defined whitelists could be exploited. The following alternatives were considered: - Making whitelist configurable via settings: Rejected due to security concerns. ### Breaking changes None ### Special notes for your reviewer The whitelist only applies to SSE-type servers with matching `baseUrl`. The implementation is minimal and focused. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A user-guide update was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
a4cc48a846 | refactor: consolidate qwen model definitions and update related references | ||
|
|
57294ab7ac | fix: update provider configurations and improve keyword matching logic | ||
|
|
68af452e3f |
feat: enhance gh-pr-review skill with multi-agent teams review and auto-fix (#13530)
### What this PR does Before this PR: The `gh-pr-review` skill was a simple single-agent PR review workflow using the `gh-pr-review` CLI extension (`EurFelux/gh-pr-review`) for structured inline comments. It only supported PR reviews. After this PR: The `gh-pr-review` skill is a comprehensive code review system inspired by [Tencent/tgfx's `.codebuddy/skills/cr`](https://github.com/Tencent/tgfx/tree/main/.codebuddy/skills/cr), adapted for Claude Code's Agent tool. It now supports: - **Multiple review modes**: local branch changes, PRs, commits, commit ranges, and file paths - **Multi-agent teams review**: parallel reviewer agents with an adversarial verifier agent to reduce false positives - **Risk-based auto-fix**: automatic fixing of low/medium/high risk issues based on user-selected mode - **Structured checklists**: code and document review checklists tailored for the project's TypeScript/React/Electron stack, with cross-references to `vercel-react-best-practices` for deeper React/performance analysis - **Self-diagnosis**: `/gh-pr-review diag` to analyze and improve the skill itself - **Checklist evolution**: mechanism to add new checklist items based on recurring patterns - **PR review via gh-pr-review extension**: retains the `gh-pr-review` CLI extension for pending reviews with inline comments, preview, and structured submission ### Why we need it and why it was done in this way The previous skill was limited to PR-only review. The tgfx approach provides a battle-tested, comprehensive review system with adversarial verification (reviewer finds issues, verifier challenges them), which significantly reduces false positives. The following tradeoffs were made: - Adapted CodeBuddy's `CreateTeam`/`SendMessage`/`TeamDelete` APIs to Claude Code's `Agent` tool with parallel subagents - Code checklist adapted for this project's specific stack (TypeScript, React 19, Electron 38, Redux Toolkit, Dexie, AI SDK v5) instead of tgfx's C++ focus - Cross-references `vercel-react-best-practices` skill for React/performance checks instead of duplicating those rules - Added v2 refactoring block rules in judgment matrix (Redux state shape / IndexedDB schema changes always deferred) - Retained `gh-pr-review` CLI extension for PR review comment submission (pending review API with preview) The following alternatives were considered: - Creating a new `/cr` skill alongside `gh-pr-review` — rejected because both serve code review and having two review skills would be confusing Links to places where the discussion took place: - Reference implementation: https://github.com/Tencent/tgfx/tree/main/.codebuddy/skills/cr ### Breaking changes None. The skill name and invocation (`/gh-pr-review`) remain the same. The `gh-pr-review` CLI extension is still used for PR reviews. New capabilities (local review, teams review, auto-fix) are additive. ### Special notes for your reviewer - The new skill routes to different reference files based on context (PR number, uncommitted changes, branch state, agent teams availability) - `references/teams-review.md` is the most complex file — it orchestrates multi-agent review with 6 phases - All reference files are adapted from tgfx's implementation with project-specific customizations - Code checklist cross-references `vercel-react-best-practices` skill for React/performance deep checks ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
21a8c625cb |
fix: add budgetTokens fallback for Agent thinking compatibility (#13575)
### What this PR does
Before this PR:
`getAnthropicReasoningParams()` could return `{ thinking: { type:
'enabled' } }` without `budgetTokens` when `findTokenLimit()` couldn't
determine a model's token limit. The Claude Agent SDK then silently
converted this to `--thinking adaptive`, which non-Anthropic upstream
providers (e.g., cherryin proxy) do not support, resulting in a 400
error: `"thinking type should be enabled or disabled"`.
After this PR:
1. Extract the shared budget computation logic into
`computeBudgetTokens()`, used by both `getThinkingBudget()` and the new
`getFallbackBudgetTokens()` to prevent drift.
2. When `getThinkingBudget()` returns `undefined`, fall back to
`getFallbackBudgetTokens()` which uses a conservative token limit (min:
1024, max: 16384) scaled by `EFFORT_RATIO`, producing values
proportional to the selected effort level.
Fixes #13573
### Why we need it and why it was done in this way
The following tradeoffs were made:
A conservative fallback max of `16384` was chosen — small enough to work
across most providers, large enough for meaningful reasoning at higher
effort levels.
The following alternatives were considered:
- Hardcoded fallback (e.g., `8192`) — rejected because it ignores effort
level and could be too large for `low` or too small for `high`.
- Modifying `getThinkingBudget()` signature to never return `undefined`
— rejected to avoid changing the existing contract for other callers.
- Skipping thinking options for non-Anthropic providers — rejected
because it would break thinking for providers that do support `enabled`
mode.
Links to places where the discussion took place: #13573, #13574
### Breaking changes
None.
### Special notes for your reviewer
- The root cause is a type mismatch between the Vercel AI SDK
(`AnthropicProviderOptions` where `budgetTokens` is optional) and the
Claude Agent SDK (where `budgetTokens` is effectively required for
`type: 'enabled'`). `getAnthropicReasoningParams` was designed for the
AI SDK but is reused in the Agent flow.
- Only `src/renderer/src/aiCore/utils/reasoning.ts` is modified.
- `getThinkingBudget()` signature and return type are unchanged.
### Checklist
- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [ ] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others
### Release note
```release-note
Fix Agent thinking mode 400 error on non-Anthropic providers by ensuring `budgetTokens` fallback with effort-based computation when token limit is unknown.
```
---------
Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
5602d820ff | fix: disable thinking mode for LLM language detection (#13565) | ||
|
|
906c6b83cc |
fix: Windows Terminal launch fails on non-English systems (#13551)
## Summary - Remove hardcoded profile name from Windows Terminal launch args - On localized Windows (e.g. Chinese), the profile is named differently, causing error 0x80070002 - Also remove extra quotes around bat file path ## Fix Use default Windows Terminal profile instead of hardcoding English profile name. Closes #13550 ## Test plan - [ ] Windows Terminal on English Windows - [ ] Windows Terminal on Chinese Windows (previously failed) - [ ] PowerShell / Command Prompt: no regression Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: George·Dong <98630204+GeorgeDong32@users.noreply.github.com> |
||
|
|
3f9cb07cbe |
fix: propagate actual stream errors instead of generic NoTextGeneratedError (#13542)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
b6f2284546 |
fix(code-tools): launch errors on Windows & Qwen Code auth issue (#13400)
### What this PR does Before this PR: - CLI tools (qwen-code, Claude Code, GitHub Copilot CLI, etc.) fail to start on Windows - bun install's multiline output (e.g., "Resolving [1/4]\nBun v1.2.9...") is misinterpreted by cmd.exe as separate commands - Users see errors like "'Resolving' is not recognized as an internal or external command" - Windows Terminal launch failed - Qwen Code auth type incorrect, in [docs](https://qwenlm.github.io/qwen-code-docs/zh/users/configuration/model-providers/) After this PR: - Redirect bun install output to a log file on Windows - Log file location: `userData/logs/cli-tools-install.log` (via `loggerService.getLogsDir()`) - Windows Terminal launch normally - Qwen Code auth type set to "openai" when package version >= 0.12.3 Fixes #12985 #13442 #13473 ### Why we need it and why it was done in this way The following tradeoffs were made: - Using file redirection (`>> "logfile" 2>&1`) instead of `--silent` flag to preserve debug information for troubleshooting - Windows-only fix since macOS/Linux terminals correctly handle multiline output The following alternatives were considered: - Using `bun install --silent`: Rejected because it would lose all debug information Links to places where the discussion took place: #12985 ### Breaking changes None ### Special notes for your reviewer - The fix uses `loggerService.getLogsDir()` to ensure logs are written to the same directory as other Cherry Studio logs - Tested on Windows with qwen-code, GitHub Copilot CLI, and other affected tools ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note Fix CLI tools failing to start on Windows by redirecting bun install output to log file ``` |
||
|
|
cb335dbcf2 |
🤖 Daily Auto I18N Sync: Mar 17, 2026 (#13521)
Co-authored-by: kangfenmao <8253512+kangfenmao@users.noreply.github.com> |
||
|
|
300920c116 |
feat: add clickable file paths to agent tool outputs and inline code (#13465)
### What this PR does Before this PR: File paths displayed in agent tool outputs (Edit, Write, Read, Glob, Grep, MultiEdit, NotebookEdit) and inline code blocks were plain, non-interactive text. After this PR: File paths are clickable — clicking opens the file directly. An ellipsis dropdown menu provides additional actions: "Reveal in Finder" and "Open in Editor" (VS Code, Cursor, Zed). ### Why we need it and why it was done in this way Clickable file paths improve developer workflow by allowing quick navigation to files referenced in agent tool outputs without manual copy-paste. The following tradeoffs were made: - A shared `ClickableFilePath` component is used across all agent tools for consistency. - Inline code file path detection uses a conservative regex (`/^\/[\w.-]+(?:\/[\w.-]+)+$/`) to avoid false positives on non-path inline code. This means some edge-case paths (e.g., with spaces or `@`) won't be detected in inline code, but tool-output paths are always clickable since they come from structured input. The following alternatives were considered: - Detecting file paths via a more permissive regex — rejected due to high false-positive risk on inline code snippets. ### Breaking changes None. ### Special notes for your reviewer - The `ClickableFilePath` component reuses existing `useExternalApps` hook and `window.api.file` IPC APIs. - i18n keys added for `open_file`, `open_file_error`, `file_not_found`, and `reveal_in_finder` across all locale files. - Review fix: hardcoded `'Finder'` string on macOS was replaced with `t()` for proper i18n compliance. - Review fix: test mocks for `openPath`/`showInFolder` now return Promises to avoid TypeError on `.catch()`. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note Add clickable file paths in agent tool outputs — click to open files, with dropdown to reveal in Finder or open in external editors (VS Code, Cursor, Zed). ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
f7ceb47462 |
fix(ci): only trigger release build on PR merge, not on every push (#13512)
### What this PR does Before this PR: The `release.yml` workflow triggers on `pull_request_target` with `opened` and `synchronize` event types. Every commit pushed to a release PR (e.g. editing release notes in `electron-builder.yml`) re-triggers the full 3-platform release build (macOS + Windows + Linux), wasting significant CI resources. After this PR: The workflow only triggers when the release PR is **merged** into `main`, not on every push. This is achieved by: 1. Changing `pull_request_target` types from `opened`/`synchronize` to `closed` 2. Adding `github.event.pull_request.merged == true` to the job condition Fixes # ### Why we need it and why it was done in this way The following tradeoffs were made: - Release builds no longer run during PR review phase. If a pre-merge test build is needed, `workflow_dispatch` can be used manually. The following alternatives were considered: - **Remove `synchronize` only (keep `opened`)**: Would still trigger on PR creation but not subsequent pushes. However, this loses automation on merge. - **Path filtering**: `pull_request_target` doesn't support `paths` filter, would require a separate job to check changed files — more complex for the same result. - **Label-based triggering**: Adds manual steps, defeats automation purpose. ### Breaking changes None. The `tag push` and `workflow_dispatch` triggers remain unchanged. The only behavioral change is that release builds now happen on merge instead of on PR open/push. ### Special notes for your reviewer - The `workflow_dispatch` trigger still allows manual release builds at any time - The `push: tags: v*.*.*` trigger is unaffected - The removed `head.repo.full_name == github.repository` check is redundant since `merged == true` already implies the PR was accepted ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
af51a27b9b |
fix(mcp): resolve hub tool auto-approve to underlying server (#13493)
### What this PR does Before this PR: When a user clicked "Auto-approve" on a hub tool (`invoke`/`exec`), the `autoApprove` function looked for a server with `id === 'hub'`, found none, and silently returned without confirming the tool or persisting the auto-approve preference. After this PR: The `autoApprove` function resolves hub tools to their underlying server via `resolveHubTool`, then correctly updates `disabledAutoApproveTools` on the real server. If resolution fails or no server is found, the tool action is still confirmed (instead of silently dropped). fixes: #13481 ### Why we need it and why it was done in this way Hub tools use a virtual `serverId` of `'hub'` which doesn't correspond to any real MCP server entry. The fix resolves the underlying server and tool name through the existing `window.api.mcp.resolveHubTool` IPC call, which is already used elsewhere in the codebase (e.g., `aiCore/utils/mcp.ts`). The following tradeoffs were made: - Duplicated the `disabledAutoApproveTools` update logic in the hub resolution branch for clarity. This keeps the hub path self-contained and avoids restructuring the existing flow. The following alternatives were considered: - Refactoring to share the update logic between hub and non-hub paths. Decided against it to keep the change minimal and focused on the bug fix. ### Breaking changes None. ### Special notes for your reviewer - The `autoApprove` callback is now `async` (it already was via `useCallback`, this just adds `await` for the IPC call). - `toolResponse` was added to the `useCallback` dependency array since it's now referenced inside the callback. - Added comprehensive tests covering all hub resolution branches (success, null result, IPC error, missing server, missing args). ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
65c9dcbdc8 |
fix: prevent horizontal scroll in agent chat messages container (#13508)
### What this PR does Before this PR: The `ChatNavigation` component at `AgentChat.tsx:103` causes an unwanted horizontal scrollbar to appear in the agent chat messages container. After this PR: Added `overflow-x-hidden` to the messages container to prevent the horizontal scrollbar caused by `ChatNavigation`. ### Why we need it and why it was done in this way The messages container already had `overflow-y-auto` for vertical scrolling, but lacked `overflow-x-hidden` to suppress the horizontal scrollbar introduced by the `ChatNavigation` component. Adding this single utility class is the minimal fix. The following tradeoffs were made: N/A The following alternatives were considered: N/A ### Breaking changes None ### Special notes for your reviewer One-line CSS change — adds `overflow-x-hidden` to the agent chat messages container div. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` |
||
|
|
83d7575695 |
fix(azure): keep dated api versions on chat transport (#13506)
## Summary Fix the Azure OpenAI regression reported in #13499. Dated Azure API versions such as `2024-12-01-preview` are intended to stay on Cherry's chat / deployment-based path, while only generic `preview` / `v1` should use the Responses API. The regression was that aiCore's internal `azure` provider still defaulted to the Responses transport, so deployment-based Azure requests could still generate `/openai/deployments/<deployment>/responses` URLs and fail with 404. This PR restores the intended split by: - making the `azure` provider default to `provider.chat(...)` - keeping `azure-responses` on `provider.responses(...)` - aligning the registry's `azure-chat` fallback with the same chat wrapper - adding regression coverage for provider routing and registry behavior ## Verification - `node node_modules/vitest/vitest.mjs run --project renderer src/renderer/src/aiCore/provider/__tests__/providerConfig.test.ts` - `node node_modules/vitest/vitest.mjs run --project aiCore packages/aiCore/src/core/providers/__tests__/registry-functionality.test.ts` Fixes #13499 Co-authored-by: cherryai002 <cherryai002@192.168.5.55> |
||
|
|
5bc235a95f | feat(agents): enhance Navbar with localized title for agent states | ||
|
|
a5ab5c2e96 |
fix(agents): fix Zed URL scheme and redesign OpenExternalAppButton (#13501)
### What this PR does
Before this PR:
- Zed editor could not open directories because it used the same VSCode
URL scheme (`vscode://file/path?windowId=_blank`), which Zed does not
recognize.
- The "Open" button always showed the first detected editor's icon
regardless of which editor the user selected from the dropdown.
- The button displayed a text label ("Open") and used an ellipsis icon
(···) for the dropdown trigger.
After this PR:
- Zed now uses the correct URL format (`zed://file/path`) matching Zed's
`strip_prefix("zed://file")` parsing logic.
- The button icon and click action update to reflect the user's last
dropdown selection.
- The button is redesigned to icon-only with a tooltip ("Open in {editor
name}") and a chevron (▼) dropdown trigger, for a cleaner look.
### Why we need it and why it was done in this way
The Zed URL scheme fix is based on reading Zed's source code
(`open_listener.rs`), which parses URLs by stripping the `"zed://file"`
string prefix — unlike VSCode which uses standard URL parsing. This
means the URL format must be `zed://file/absolute/path` (no extra `/`
between `file` and the path, no query params).
The icon-only button redesign with tooltip follows common split-button
patterns for a more compact and intuitive UI.
The following alternatives were considered:
- Using `shell.openExternal` via IPC instead of `window.open()` —
unnecessary since `window.open()` works for all three editors.
### Breaking changes
None.
### Special notes for your reviewer
- The pre-existing typecheck failures in CI are unrelated to this PR
(they are in `aiCore/plugins`, `store/messageBlock.ts`, etc.).
### Checklist
- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [ ] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others
### Release note
```release-note
Fix Zed editor unable to open directories from agent workspace, and redesign the "Open in editor" button to icon-only with tooltip and editor selection memory.
```
---------
Signed-off-by: beyondkmp <beyondkmp@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Phantom <eurfelux@gmail.com>
|
||
|
|
a2ac99c8da |
chore: release v1.8.0 (#13500)
### What this PR does Release Cherry Studio v1.8.0 with new features, bug fixes, and improvements. ### Release Notes Cherry Studio 1.8.0 - Agents & Performance ✨ New Features - [Agents] Added drag-and-drop manual sorting for agent and session lists - [Models] Added MiniMax M2.5 highspeed model support 🐛 Bug Fixes - [Agents] Fixed deleting last accessible directory bug - delete button now disabled when only one remains - [UI] Fixed web search providers not showing for local models (e.g., Ollama) in chat toolbar - [Models] Fixed reasoning effort and summary mode not applying for some OpenAI-compatible providers - [Gateway] Fixed gateway status detection for crashed/externally-stopped gateways - [Gateway] Improved gateway startup error messages with detailed diagnostics - [Poe] Fixed web_search parameter not being passed correctly when built-in search is enabled 💄 Improvements - [Agents] Added configurable maximum tool calls setting (1-100) in assistant settings - [UI] Added Windows Mica effect for better visual integration - [Performance] Increased default request timeout from 10 to 30 minutes for slow local models ### Included Commits -v1.8.0 |
||
|
|
888ce83fc7 |
feat(streaming): replace fixed timeout with resettable idle timeout (#13497)
### What this PR does Before this PR: The streaming timeout used a fixed `AbortSignal.timeout()` that starts counting from the initial request. For long-running SSE streams (e.g., complex reasoning or tool-calling chains), the request could be aborted even while data was actively flowing. After this PR: Introduces an `IdleTimeoutController` that resets its countdown every time a stream chunk is received. The timeout now only fires when the stream is truly idle (no data received for the configured duration), not based on total elapsed time. Fixes #13489 ### Why we need it and why it was done in this way The following tradeoffs were made: - The idle timeout controller is a simple utility class with `reset()` and `cleanup()` methods, exposed via an `IdleTimeoutHandle` interface and threaded through `ModernAiProviderConfig` to `AiSdkToChunkAdapter`. - The `reset()` callback is invoked on every `reader.read()` return in `readFullStream`, which is the natural place where SSE chunks are consumed. - `cleanup()` is called in the `finally` block to prevent timer leaks when the stream ends normally or errors out. The following alternatives were considered: - Implementing idle timeout at the AI SDK level — not feasible as the AI SDK does not support idle timeout natively. - Using a wrapper around `reader.read()` with `Promise.race` — more invasive and less clean than resetting a timer on each chunk. ### Breaking changes None. The default timeout duration remains unchanged (30 minutes). The only behavioral change is that the timeout now resets on each chunk instead of being fixed from request start. ### Special notes for your reviewer - The `IdleTimeoutController` is covered by 6 unit tests (fake timers). - The new optional `idleTimeout` constructor parameter on `AiSdkToChunkAdapter` is backward-compatible — existing callers (e.g., `messageThunk.ts`) are unaffected. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780096809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
31cd13ae8b |
fix(agents): improve navbar layout for agent status screens (#13494)
### What this PR does Before this PR: - Agent status screens (Disabled, Stopped, Empty) did not show the Navbar component - AgentSidePanel tabs had incorrect padding when navbar is at top position - AgentStatusScreen used motion animation which was unnecessary <img width="1060" height="700" alt="image" src="https://github.com/user-attachments/assets/ec90c9ed-f8a9-4c1d-a9a4-af2ef34ab772" /> After this PR: - All agent status screens now consistently display the Navbar component - AgentSidePanel tabs padding adjusts correctly based on navbar position (adds `pt-0.5` when navbar is at top) - Removed motion animation from AgentStatusScreen for cleaner code - AgentNavbar is always shown regardless of navbar position setting <img width="1060" height="700" alt="image" src="https://github.com/user-attachments/assets/fee0aaa6-d49b-4dd8-819d-6f7a0b083945" /> ### Why we need it and why it was done in this way The following tradeoffs were made: - Removed motion animation to simplify the component; the animation was brief and not critical to UX The following alternatives were considered: - Using CSS attribute selectors for navbar position styling, but using the existing `useNavbarPosition` hook is more consistent with the codebase ### Breaking changes None ### Special notes for your reviewer This is a UI layout fix to ensure consistent navbar display across all agent page states. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [ ] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
590815bbd5 |
fix(openclaw): improve gateway startup diagnostics and fix UI polling loop (#13495)
### What this PR does Before this PR: - Gateway startup failures showed limited diagnostics (only stderr, no stdout) - OpenClawPage had infinite re-render loops caused by `setInterval` + `dispatch` in `useEffect` deps - Process exit with code 0 was not properly diagnosed when the daemonized child failed After this PR: - Capture both stdout and stderr from the gateway process for better failure diagnostics - Replace `setInterval` polling with SWR for stable, dedup'd status/health polling in the UI - Improve error messages for gateway startup timeout (combine health, stderr, stdout diagnostics) - Handle edge case where gateway exits with code 0 but never becomes healthy ### Why we need it and why it was done in this way The infinite re-render loop in the renderer was the root cause of false timeout errors during gateway health checks. Switching to SWR provides stable polling without the pitfall of `setInterval` + `dispatch` in `useEffect` deps. The diagnostics improvements (stdout capture, combined error output) are independent quality-of-life improvements that help debug gateway startup failures. ### Breaking changes None. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
878861db84 |
fix(scripts): add fallback to GitCode mirror when GitHub download fails (#13492)
## Summary - When GitHub is inaccessible, the openclaw installation script now automatically falls back to GitCode mirror instead of failing with error code 103 - Added `downloadWithFallback` function that tries GitHub first, then GitCode mirror - If `OPENCLAW_USE_MIRROR=1` is set, the order is reversed (GitCode first, then GitHub) ## Test plan - [ ] Test installation with GitHub accessible - [ ] Test installation with GitHub blocked (should fallback to GitCode mirror) - [ ] Test installation with `OPENCLAW_USE_MIRROR=1` environment variable Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
6eb461dd19 |
feat(skills): add vercel-react-best-practices skill (#13424)
### What this PR does Before this PR: No React/Next.js performance best practices skill available for AI coding agents. After this PR: Adds the `vercel-react-best-practices` skill from `vercel-labs/agent-skills`, providing 60+ React and Next.js performance optimization rules covering rendering, re-renders, bundling, async patterns, server components, and JS performance. ### Why we need it and why it was done in this way The following tradeoffs were made: - This skill includes ~8 Next.js server-specific rules (`server-*`, `async-api-routes`) that are not applicable to our Electron + React project. We chose to keep them rather than fork/trim the skill, since: (1) AI agents will naturally ignore irrelevant rules based on context, (2) keeping the full skill makes future upstream updates easier, and (3) the ~50 React/JS/rendering/bundle rules provide significant value for our codebase. The following alternatives were considered: - Forking the skill and removing Next.js-specific rules — rejected to avoid maintenance burden and divergence from upstream. - Writing a custom React-only skill — rejected as the Vercel skill already covers the React patterns comprehensively. Links to places where the discussion took place: - Source: https://github.com/vercel-labs/agent-skills ### Breaking changes None ### Special notes for your reviewer - The skill is installed in `.agents/skills/vercel-react-best-practices/` as the single source of truth. - `.claude/skills/vercel-react-best-practices` is a **directory symlink** pointing to `.agents/skills/vercel-react-best-practices/`, following the convention established in #13486. This replaces the earlier approach of copying SKILL.md into a real directory. - `public-skills.txt` was updated and `pnpm skills:sync` was run to update `.gitignore` whitelists. - Windows compatibility: Windows developers need symlink support enabled (via `git config core.symlinks true` or Developer Mode). This is consistent with the project-wide symlink convention adopted in #13486, and confirmed working by @GeorgeDong32 on Windows 11 — Claude Code CLI can load skills even when symlinks fall back to plaintext path files. - The skill contains 60+ markdown rule files covering categories: rendering, re-renders, bundle optimization, async patterns, server components, client patterns, and JS performance. - Rule applicability breakdown for our Electron + React project: | Category | Count | Applicable | |---|---|---| | `js-*` (JS perf) | 13 | Yes | | `rerender-*` (React) | 12 | Yes | | `rendering-*` | 11 | Mostly | | `bundle-*` | 5 | Partially | | `client-*` | 4 | Yes | | `advanced-*` | 3 | Yes | | `async-*` | 4 | Partially | | `server-*` (Next.js) | 8 | No | ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: icarus <eurfelux@gmail.com> |
||
|
|
74c892fe1a |
fix(agents): prevent deleting the last accessible directory (#13483)
### What this PR does Before this PR: Deleting the only accessible directory in Agent Settings fails silently — `resolveAccessiblePaths()` treats `[]` the same as `undefined`, replacing it with a default path. The directory reappears after deletion. After this PR: - Backend: `AgentService.updateAgent()` and `SessionService.updateSession()` reject empty `accessible_paths` with an explicit error, enforcing the existing non-empty constraint. - Frontend: The delete button is disabled (with a tooltip) when only one accessible directory remains. <img width="362" height="207" alt="image" src="https://github.com/user-attachments/assets/4cd62081-ce77-46f7-bf0c-ca37be7f76cb" /> Fixes #13469 ### Why we need it and why it was done in this way The existing `resolveAccessiblePaths()` already assumes at least one path (Claude Code session startup requires `accessible_paths[0]` as cwd). Rather than changing this contract, we enforce it at both layers: The following tradeoffs were made: - Chose to disable the button rather than hide it, so users understand the constraint. - Used existing i18n key `agent.session.accessible_paths.error.at_least_one` for the tooltip. The following alternatives were considered: - Allowing empty `accessible_paths` and handling it at runtime — rejected because session startup already depends on non-empty paths, and silently failing is worse UX. - Only fixing backend or only frontend — rejected in favor of defense-in-depth (frontend prevents the action, backend validates the invariant). ### Breaking changes None. ### Special notes for your reviewer `resolveAccessiblePaths()` in `BaseService.ts` is intentionally **not** modified — its existing behavior (fallback to default for both `undefined` and `[]`) remains correct for the **creation** path. The fix targets only the **update** path where `[]` should be rejected rather than silently replaced. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note Fixed a bug where deleting the last accessible directory in Agent Settings would fail silently. The delete button is now disabled when only one directory remains. ``` Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
fe0678a206 |
chore: migrate .claude/skills to directory symlinks (#13486)
### What this PR does Before this PR: `.claude/skills/<name>/SKILL.md` files were **copied** from `.agents/skills/<name>/SKILL.md` via `pnpm skills:sync`. A dedicated `skills-check-windows` CI job ran on `windows-latest` to verify cross-platform file-copy compatibility. After this PR: `.claude/skills/<name>` entries are **directory symlinks** pointing to `../../.agents/skills/<name>`, following the Single Source of Truth (SSoT) principle. The Windows-specific CI job is removed; Windows developers are expected to enable symlink support. ### Why we need it and why it was done in this way The following tradeoffs were made: - Windows developers must now manually enable symlink support (Developer Mode + `git config --global core.symlinks true`). This is acceptable because: 1. The existing `AGENTS.md` is already a symlink, so Windows compatibility was never fully enforced. 2. Symlinks eliminate the need for file-copy synchronization, reducing maintenance complexity. 3. Contributors are expected to have sufficient technical capability to configure their environments. The following alternatives were considered: - Keeping file-copy sync: rejected because it duplicates content and requires extra CI to verify consistency. ### Breaking changes Windows developers who clone without symlink support enabled will get plain text files instead of symlinks. They must: 1. Enable Developer Mode or grant `SeCreateSymbolicLinkPrivilege` 2. Run `git config --global core.symlinks true` 3. Re-clone or run `pnpm skills:sync` ### Special notes for your reviewer - The `.github/workflows/ci.yml` diff includes minor quote-style changes (`'` → `"`) from the YAML formatter — these are cosmetic only. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [ ] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
19bd2cdd93 | feat(ui): enable windows mica effect (#13476) | ||
|
|
8b98b8f9c6 |
fix(agents): use correct SWRInfinite cache key and add optimistic update for session editing
Fixes SWRInfinite cache key usage and adds optimistic updates for session editing. |
||
|
|
c6ce1deecd |
fix(ui): show web search providers for all models (#13472)
### What this PR does Before this PR: Web search provider options (Tavily, SearXNG, etc.) were only shown for models matching `isFunctionCallingModel()` or when the user explicitly set prompt tool-use mode. Local LLM models (e.g. Ollama) showed an empty web search panel. After this PR: Web search provider options are always available for all models. Fixes #13466 ### Why we need it and why it was done in this way At runtime, models that lack native function-calling support automatically fall back to prompt-based tool use (`ApiService.ts:254-256`), so web search providers work regardless of model capability. The UI gate was unnecessarily restrictive and out of sync with runtime behavior. The following tradeoffs were made: - This removes the UI-level capability check entirely. A discussion point is whether users should be informed that prompt-based tool use is being used as a fallback (no visual indicator currently exists). The following alternatives were considered: - Matching the gate to the runtime fallback condition (`isFunctionCallingModel || isToolUseModeFunction`) — rejected because prompt mode has almost no model restrictions, making any gate unnecessary. ### Breaking changes None. ### Special notes for your reviewer **Behavior change**: selecting a web search provider on a non-function-calling model now silently triggers prompt-based tool use at runtime (this fallback already existed but was previously unreachable from the UI). Please consider whether this implicit fallback is acceptable or if it needs a user-visible indicator. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: N/A - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note Fixed web search provider options not showing for local LLM models (e.g. Ollama) in the chat input toolbar. ``` Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e860dd448f |
feat(agents): add manual drag-and-drop sorting for agent and session lists (#13460)
### What this PR does
Before this PR:
Agents and sessions in the sidebar are listed in fixed order with no way
to manually reorder them.
After this PR:
Both agents and sessions can be reordered via drag-and-drop. The order
is persisted to the SQLite database via a new `sort_order` column, and
new items are automatically placed at the top of the list. Session
sorting is scoped per-agent (each agent's sessions are independently
sortable).
### Why we need it and why it was done in this way
The following tradeoffs were made:
- Used `sort_order` integer column in SQLite (backend persistence)
rather than Redux/localStorage, because agents/sessions data lives in
the backend DB — consistent with the existing architecture.
- New agents/sessions get `sort_order = 0` and all existing items are
shifted up by 1, matching the assistant list behavior where new items
appear at the top.
- Reused `DraggableList` component for agents and `DraggableVirtualList`
for sessions (both using `@hello-pangea/dnd`) for consistency with
existing drag-and-drop patterns.
- Added dedicated `PUT /v1/agents/reorder` and `PUT
/v1/agents/{agentId}/sessions/reorder` endpoints rather than updating
sort_order through individual PATCH calls, to ensure atomic reorder
operations.
The following alternatives were considered:
- Storing order in Redux/localStorage — rejected because agents/sessions
are fetched from the backend SQLite DB via HTTP API, so the order would
diverge.
- Using `@dnd-kit/sortable` instead of `@hello-pangea/dnd` — rejected to
maintain consistency with existing components.
### Breaking changes
None. The new `sort_order` column defaults to `0` for all existing
agents and sessions, so they will share the same sort order initially
and fall back to `created_at DESC` as tie-breaker.
### Special notes for your reviewer
**Database migration:**
- `0003_slippery_wild_pack.sql` adds `sort_order INTEGER NOT NULL
DEFAULT 0` to both `agents` and `sessions` tables
- Schema defines indexes (`idx_agents_sort_order`,
`idx_sessions_sort_order`) for query performance
- Existing rows get `sort_order = 0` by default; the first reorder
operation will assign proper values
**API changes:**
- `PUT /v1/agents/reorder` — accepts `{ ordered_ids: string[] }` to
reorder agents
- `PUT /v1/agents/{agentId}/sessions/reorder` — accepts `{ ordered_ids:
string[] }` to reorder sessions (scoped to agent)
- `GET /v1/agents` — default sort changed to `sort_order ASC, created_at
DESC`
- `GET /v1/agents/{agentId}/sessions` — default sort changed to
`sort_order ASC, created_at DESC`
**Frontend:**
- `useAgents` hook exposes `reorderAgents()` with optimistic SWR cache
update
- `useSessions` hook exposes `reorderSessions()` with optimistic
SWRInfinite cache update (preserves real total for pagination)
- `AgentSidePanel` uses `DraggableList` for agent drag-and-drop
- `Sessions` component swapped from `DynamicVirtualList` to
`DraggableVirtualList` for session drag-and-drop
**Atomicity:**
- `createSession` wraps sort_order shift + insert in a transaction
- `reorderAgents` and `reorderSessions` both use transactions
### Checklist
- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A user-guide update was considered and is present
(link) or not required. Check this only when the PR introduces or
changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code before requesting review
from others
### Release note
```release-note
Added drag-and-drop manual sorting for agent and session lists in the sidebar panel.
```
---------
Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: kangfenmao <kangfenmao@qq.com>
|
||
|
|
f0f04eeda0 |
docs: update agents.db path in CLAUDE.md after #13392 (#13471)
### What this PR does Before this PR: CLAUDE.md described agents.db path as `~/.cherrystudio/data/agents.db` (dev) / `userData/agents.db` (prod), which is outdated after #13392. After this PR: Updated to reflect the unified path `{userData}/Data/agents.db` with macOS examples for both dev and prod. Fixes # N/A ### Why we need it and why it was done in this way The following tradeoffs were made: None. Straightforward documentation update. The following alternatives were considered: N/A Links to places where the discussion took place: https://github.com/CherryHQ/cherry-studio/pull/13392 ### Breaking changes None. ### Special notes for your reviewer N/A ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
46ad0fa5d8 |
feat: add MiniMax-M2.5-highspeed model (#13470)
## Summary Add the `MiniMax-M2.5-highspeed` model to both `minimax` (CN) and `minimax-global` provider model lists. ## Changes - Add `MiniMax-M2.5-highspeed` model entry to the `minimax` provider model list - Add `MiniMax-M2.5-highspeed` model entry to the `minimax-global` provider model list ## Context `MiniMax-M2.5-highspeed` is an officially available MiniMax model that offers the same performance as `MiniMax-M2.5` but with faster inference speed and more agility. It supports 204,800 tokens context window. - API Documentation: https://platform.minimax.io/docs/api-reference/text-openai-api Signed-off-by: octo-patch <octo-patch@users.noreply.github.com> Co-authored-by: octo-patch <octo-patch@users.noreply.github.com> |
||
|
|
774cb7a73c |
fix(openclaw): fix gateway status detection and improve error reporting (#13433)
### What this PR does Before this PR: - `getStatus` only probed health when status was `stopped` or `error`. If the gateway crashed while status was `running`, the UI would never detect the crash and keep showing "运行中" (running). - `checkHealth` probed the gateway but never updated `gatewayStatus`, so a failed health check had no lasting effect. - `startAndWaitForGateway` spawned the process with `stdio: 'ignore'`, discarding stderr. On startup failure, the user only saw "gateway exited with code 1" with no actionable detail. - `parseUpdateStatus` matched any update channel (npm, pkg, binary), causing false positives for binary-installed users when only an npm/pkg update was available. After this PR: - `getStatus` probes health in all non-`starting` states, transitioning `running → stopped` when the gateway is unreachable. - `checkHealth` syncs `gatewayStatus` to `stopped` when the probe returns unhealthy. - `startAndWaitForGateway` pipes stderr and extracts the first 3 lines of error output for meaningful error messages. - `parseUpdateStatus` only matches binary-channel updates, ignoring npm/pkg channels. - 29 new state-machine tests cover all gateway status transitions and lifecycle scenarios. Fixes # ### Why we need it and why it was done in this way The gateway status was a one-way latch: once set to `running`, it could only be changed by an explicit `stopGateway` call. External crashes (process killed, config errors, port conflicts) left the UI in an incorrect state. The following tradeoffs were made: - `getStatus` now always calls `probeGatewayHealth` (except during `starting`). This adds a small overhead per status poll, but is necessary for correctness since the gateway process lifecycle is independent (detached). - stderr capture uses `['ignore', 'ignore', 'pipe']` instead of full `'pipe'` to minimize resource usage — we only need stderr for error diagnostics. The following alternatives were considered: - Keeping a persistent health-check interval timer — rejected as over-engineered for the current polling-based UI. - Parsing the full `openclaw update status` table structure — rejected in favor of simple regex matching on the `binary` channel keyword. ### Breaking changes None. ### Special notes for your reviewer - The `parseUpdateStatus` change means users who installed OpenClaw via npm will no longer see update notifications in Cherry Studio. This is intentional — Cherry Studio only manages binary installations. - The test file grew significantly (from 90 lines to 595 lines) because this is the first time the `OpenClawService` class has state-machine test coverage. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note fix(openclaw): gateway status now correctly detects crashed/externally-stopped gateways; startup errors show detailed messages instead of generic exit codes; update checker only reports binary-channel updates ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
f3244c3e9e |
fix(aiCore): bypass AI SDK model ID allowlist for reasoning detection (#13463)
### What this PR does Before this PR: When using reasoning models (e.g., GPT-5.2) through third-party OpenAI-compatible providers that use the Responses API endpoint, `reasoningEffort` and `reasoningSummary` settings from the UI are silently ignored. The AI SDK logs a warning: `reasoningEffort is not supported for non-reasoning models`. After this PR: Reasoning parameters are correctly included in the Responses API request body for all providers, regardless of model ID format. Fixes #13454 ### Why we need it and why it was done in this way The following tradeoffs were made: The `@ai-sdk/openai` Responses model uses a hardcoded model ID allowlist (`modelId.startsWith('gpt-5')`, etc.) to determine if a model supports reasoning. Third-party providers often use non-canonical model IDs (e.g., `openai/gpt-5.2`) that fail these checks, causing reasoning params to be silently dropped. The fix uses `forceReasoning: true` — a bypass mechanism provided by the AI SDK — when Cherry Studio's own `isReasoningModel()` detects the model as a reasoning model. This is semantically correct: Cherry Studio's model detection is more comprehensive than the AI SDK's allowlist. The following alternatives were considered: - Migrating to `@ai-sdk/open-responses` (tracked in #13462) — better long-term solution but larger scope - Stripping model ID prefixes before passing to the AI SDK — fragile and provider-specific - Using `openai-compatible` provider with manual reasoning parameter handling — would lose Responses API features ### Breaking changes None. ### Testing - [x] Manual test passed: confirmed `reasoning.effort` and `reasoning.summary` are now correctly included in the Responses API request body when using a third-party provider with non-canonical model IDs. ### Special notes for your reviewer - The `forceReasoning` option is an official AI SDK feature, not a hack. It's documented for exactly this use case: "stealth" reasoning models where the model ID is not recognized by the SDK's allowlist. - `isReasoningModel(model)` is used instead of `enableReasoning` because `forceReasoning` should reflect model capability, not user preference. - A TODO comment links to #13462 for the longer-term migration to `@ai-sdk/open-responses`. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A user-guide update was considered and is present (link) or not required. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note fix: reasoning effort and summary mode settings now correctly apply for third-party OpenAI-compatible providers using the Responses API endpoint ``` Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
d676b3b39a |
chore: add Zed editor settings example, clean up configs, and improve dev guides (#13457)
### What this PR does Before this PR: - No Zed editor configuration example existed for contributors using Zed - Several config files had inconsistent JSON array formatting - `biome.jsonc` had redundant exclude rules - Contributing guides did not reference the development guide - `development.md` (zh) was not translated to Chinese - Node.js and pnpm versions were hardcoded in the development guide After this PR: - Added `.zed/settings.json.example` with Biome formatter, oxc/eslint/biome fixAll, and import organization - Cleaned up redundant Biome exclude rules and unified JSON array formatting - Added "Setting Up Your Development Environment" section to `CONTRIBUTING.md` (en/zh) linking to the development guide - Added Zed editor setup guide to `development.md` (en/zh) - Translated `docs/zh/guides/development.md` to Chinese - Node.js version now references `.node-version`; pnpm version references `packageManager` in `package.json` - VSCode extensions now reference `.vscode/extensions.json` ### Why we need it and why it was done in this way The following tradeoffs were made: - The Zed settings file is provided as an `.example` rather than a direct `.zed/settings.json` to avoid overriding individual contributor preferences. - Versions reference their source of truth files rather than being hardcoded, so docs stay in sync automatically. The following alternatives were considered: - N/A ### Breaking changes None ### Special notes for your reviewer - The JSON formatting changes are purely cosmetic — no behavior changes. They align with Biome's default formatting rules. - The `.zed/settings.json.example` includes `source.fixAll.eslint` and `source.fixAll.oxc` alongside Biome, matching the project's triple-linter setup. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
aeae3be69c |
fix: increase default request timeout from 10 to 30 minutes (#13453)
### What this PR does Before this PR: The default request timeout for LLM API calls was 10 minutes. When using local models (e.g., LM Studio with Qwen 3.5 28b), the model may take longer than 10 minutes to process input data, causing a `TimeoutError` / `AbortError` before the model finishes responding. After this PR: The default request timeout is increased to 30 minutes, giving local models enough time to complete inference. Fixes #13452 ### Why we need it and why it was done in this way Local models running on consumer hardware (e.g., via LM Studio, Ollama) can take significantly longer to process requests compared to cloud APIs. The previous 10-minute timeout was insufficient for large local models like Qwen 3.5 28b. The following tradeoffs were made: This is a temporary fix as discussed in the issue. User-configurable timeout settings will be available after v2.0.0. The following alternatives were considered: - Per-provider timeout configuration (deferred to v2) - Separate timeout for local vs cloud providers (unnecessary complexity for a temporary fix) ### Breaking changes None. ### Special notes for your reviewer The `DEFAULT_TIMEOUT` constant is used across both the new AI Core path (`parameterBuilder.ts`) and the legacy client path (`BaseApiClient.ts`). The flex service tier timeout (15 min) is now shorter than the default (30 min), but flex tier models are cloud-hosted and unlikely to need more than 15 minutes. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A user-guide update was considered and is present (link) or not required. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note Increased the default request timeout from 10 minutes to 30 minutes, preventing premature timeout errors when using slow local models (e.g., LM Studio, Ollama). ``` Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
9c3c990365 |
feat: separate Agent into independent module with dedicated page and route (#13420)
### What this PR does Before this PR: Agent and Assistant were mixed in a single `UnifiedList` in the home page sidebar. Users had difficulty discovering the Agent entry. The two have fundamentally different data models (Redux vs SQLite), interaction patterns (topic vs session), and component hierarchies, yet shared the same UI components and Redux state (`activeTopicOrSession`). After this PR: Agent is separated into an independent module with its own sidebar entry, route (`/agents`), page, navbar, and side panel. The home page only handles Assistants. Navigation between the two is handled via sidebar icons and routes, not Redux state. Fixes #13329 ### Why we need it and why it was done in this way The following tradeoffs were made: - `AgentSettingsTab` was moved to `pages/agents/` and is used by the `AgentChatNavbar/Tools/SettingsButton` drawer. - `Unified*` components were renamed to `Assistant*` (via `git mv`) rather than just removing agent code, to make naming accurate and improve readability. - `activeTopicOrSession` was removed from Redux runtime store entirely, replaced by route-based detection where needed, avoiding stale state issues. The following alternatives were considered: - Keeping a shared `UnifiedList` with a filter — rejected because the data models and interaction patterns are too different, leading to excessive conditional logic. - Using a tab within the home page — rejected per issue spec; agents need their own sidebar entry and dedicated page for discoverability. ### Breaking changes None. This is an internal UI refactoring. The Redux migration (v200 → v201) automatically adds the `'agents'` sidebar icon to existing user configurations. ### Special notes for your reviewer **New directory structure — `pages/agents/`:** - `AgentPage.tsx` — Top-level page with apiServer.enabled guard (early return with alert when server disabled) - `AgentChat.tsx` — Chat area with loading state management (Spin during initialization, alerts for select/create states) - `AgentNavbar.tsx` — Top navbar for left-sidebar layout mode - `AgentSidePanel.tsx` — Left panel with agent list and sessions tabs - `AgentSettingsTab.tsx` — Moved from home, used by AgentChatNavbar settings drawer - `components/AgentChatNavbar/` — Mirrors `home/components/ChatNavBar/` structure: - `index.tsx` — Sidebar toggle buttons + content wrapper - `AgentContent.tsx` — Agent → Session → Model → Workspace breadcrumb navigation - `Tools/` — Agent-specific toolbar with `SettingsButton` (uses `AgentSettingsTab`) - `OpenExternalAppButton.tsx`, `SessionWorkspaceMeta.tsx` — AgentContent-only components - `components/` — Migrated agent-only components: `AgentItem`, `AgentSessionInputbar`, `AgentSessionMessages`, `SelectAgentBaseModelButton`, `SessionItem`, `Sessions` **Hook consolidation:** - Merged two duplicate `useActiveAgent` hooks into one at `hooks/agents/useActiveAgent` — now returns both `{ agent, error, isLoading, setActiveAgentId }` - Deleted `home/Tabs/hooks/useActiveAgent.ts` **Loading state improvements:** - `AgentPage` top-level guard prevents all child components from rendering when apiServer is disabled - `AgentChat` tracks `isInitializing` covering: server starting → agents loading → agent loading → session initializing → auto-select pending - `useAgentSessionInitializer` now distinguishes `undefined` (not initialized) vs `null` (initialized, no sessions) in `activeSessionIdMap`, preventing premature "create session" alerts **Shared component extraction:** - `AddButton` moved from `home/Tabs/components/` to `renderer/src/components/` (used by both pages) ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A user-guide update was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note Added a dedicated "Agents" page accessible from the sidebar, separating Agents from the Assistants list for improved discoverability and clearer navigation. ``` --------- Signed-off-by: icarus <eurfelux@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
ea694c630c |
feat(assistant): add configurable max tool calls setting (#13398)
### What this PR does **Before this PR:** The MCP tool call limit was hard-coded to 20 in `parameterBuilder.ts`: ```typescript stopWhen: stepCountIs(20) ``` Users could not customize this limit, which was reported in #13370 as a limitation for workflows requiring more tool calls. **After this PR:** - Added configurable `maxToolCalls` setting (range: 1-100) in Assistant Settings → Model Settings - Added `enableMaxToolCalls` toggle to control the feature - Default behavior unchanged: 20 tool calls limit (matching AI SDK default) - Users can increase the limit if their workflow requires more tool calls - All i18n translations added for 11 languages Fixes #13370 ### Why we need it and why it was done in this way **Tradeoffs:** - Default value kept at 20 to prevent infinite loops and maintain backward compatibility - Range limited to 1-100 to prevent excessive token usage and API costs **Alternatives considered:** - Setting default to "unlimited" - rejected because AI SDK designed 20 as default for safety - Making it a global setting - rejected because different assistants may need different limits ### Breaking changes None. Default behavior remains unchanged (20 tool calls). Existing users will continue to have the same experience. ### Special notes for your reviewer - The `enableMaxToolCalls` field defaults to `true` to maintain the original 20-call behavior - When disabled, it still uses 20 (AI SDK's default), not unlimited - `getAssistantSettings()` properly returns the new fields for consistent access ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note ```release-note Added configurable maximum tool calls setting for assistants. Users can now customize the tool call limit (1-100) in Assistant Settings → Model Settings. Default remains at 20 calls to prevent infinite loops, matching AI SDK's design. ``` --------- Co-authored-by: icarus <eurfelux@gmail.com> |
||
|
|
97011c8bb2 |
feat(openclaw): binary download install, auto update check, and gateway refactor (#13440)
### What this PR does Refactors OpenClaw installation to use direct binary downloads instead of npm, adds auto update detection, and delegates gateway lifecycle to OS service manager CLI commands. **Binary download install (replaces npm install):** - Download pre-built binaries from GitHub releases (or gitcode.com mirror for China users) - Install to `~/.cherrystudio/bin/` — no npm/Node.js dependency required - Uninstall by simply deleting the binary file - Detect old npm-installed versions and prompt migration **Auto update check:** - Automatically check for updates via `openclaw update status` when entering the OpenClaw page - Show info alert with version details when an update is available - Perform update via `openclaw update` command (stops gateway first if running) - Version parsing extracted to `services/utils/openClawParsers.ts` with inline snapshot tests **Gateway lifecycle refactor:** - Gateway lifecycle delegated to OS service manager via `openclaw gateway` CLI commands - Removes in-process `ChildProcess` management, `node:net` Socket probing, and `killProcess` helper - Health checks use `openclaw gateway health` CLI command - `getStatus` is now async and probes health to detect externally-started gateways - Return type unified to discriminated union `OperationResult` **Windows-specific handling:** - Skip `gateway install/uninstall` (scheduled task integration has upstream bugs) - Gateway started via `openclaw gateway start --force` - Port conflict detection before startup with clear error messages **UI improvements:** - Auto update alert with "Reinstall" button when new version detected - Copy button on install/uninstall log container and error alerts ### Why we need it and why it was done in this way - Binary download is faster, more reliable, and removes the npm/Node.js dependency for end users - `openclaw update` leverages the tool's built-in update mechanism rather than re-downloading - Delegating to OS service management (launchd/systemd) is more robust — the gateway survives app restarts - Version parsers are pure functions with snapshot tests to prevent regressions ### Breaking changes None. Internal refactoring only — no user-facing API changes. ### Special notes for your reviewer - New IPC channels: `OpenClaw_CheckUpdate`, `OpenClaw_PerformUpdate` - New file: `src/main/services/utils/openClawParsers.ts` (pure parsing functions) - New test: `src/main/services/__tests__/OpenClawService.test.ts` (16 snapshot tests) - i18n: added `openclaw.update.*` and `openclaw.quick_actions.check_update` keys (all locales synced) - Windows: no service registration, gateway started with `--force`, port checked before startup - macOS/Linux: full service lifecycle via CLI commands ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note feat(openclaw): switch to binary download install and add auto update check fix(openclaw): gateway start or stop exception ``` --------- Co-authored-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
4aef249151 |
fix: correctly pass poe web_search via extra_body when built-in search is enabled (#13434)
Fix #13305 > https://creator.poe.com/docs/external-applications/openai-compatible-api#using-custom-parameters-with-extra_body ```js import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.POE_API_KEY, baseURL: "https://api.poe.com/v1", }); // Example: Using web search and thinking level with Gemini models const response = await client.chat.completions.create({ model: "Gemini-3-Pro", messages: [{ role: "user", content: "What are the latest developments in quantum computing?" }], extra_body: { web_search: true, thinking_level: "high" } }); ``` ```release-note fix(poe): correctly pass poe web_search via extra_body when built-in search is enabled ``` |
||
|
|
8dd42eb8ba |
chore: release v1.7.25 (#13438)
### What this PR does Before this PR: - Version is 1.7.24 After this PR: - Version is 1.7.25 - Release notes updated in `electron-builder.yml` ### Why we need it and why it was done in this way Standard release workflow: collect commits since v1.7.24, generate bilingual release notes, bump version. The following tradeoffs were made: N/A The following alternatives were considered: N/A ### Breaking changes **Action Required**: The built-in filesystem MCP server now requires manual approval for write/edit/delete operations by default. ### Special notes for your reviewer **Included commits since v1.7.24:** ✨ New Features: - feat(websearch): add Querit search provider (#13050) - feat(minapp,provider): add MiniMax Agent, IMA mini apps and MiniMax Global, Z.ai providers (#13099) - feat(provider): add agent support filter for provider list (#11932) - feat(agent): add custom environment variables to agent configuration (#13357) - feat: add GPT-5.4 support (#13293) - feat(gemini): add thought signature persistence (#13100) 🐛 Bug Fixes: - fix: secure built-in filesystem MCP root handling (#13294) - fix: check underlying tool permissions for hub invoke/exec (#13282) - fix: remove approval countdown timers and add system notifications (#13281) - fix: agent tool status not stopping on abort (#13111) - fix: resolve spawn ENOENT on Windows for Code Tools (#13405) - fix: Use default assistant for topic auto-renaming (#13387) - fix(backup): defer auto backup during streaming response (#13307) - fix(ui): fix Move To submenu overflow (#13399) - fix: render xml fenced svg blocks as svg previews (#13431) - fix: correct Gemini reasoning params (#13388) - fix: improve Qwen 3.5 reasoning model detection (#13235) - fix: upgrade xAI web search to Responses API (#12812) - fix(api-server): relax chat completion validation (#13279) - fix: install or uninstall button state issues (#13114) - fix: improve update dialog behavior (#13363) - fix: auto-convert reasoning_effort to reasoningEffort (#12831) ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A user-guide update was considered and is present (link) or not required. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note See release notes in electron-builder.yml ``` --------- Signed-off-by: kangfenmao <kangfenmao@qq.com>v1.7.25 |
||
|
|
5463c83ee2 |
refactor(openclaw): unify package to openclaw, remove openclaw-zh (#13436)
### What this PR does Before this PR: - OpenClaw installation used different npm packages based on user location: `@qingchencloud/openclaw-zh@latest` for China users and `openclaw@latest` for others After this PR: - All users install the unified `openclaw@latest` package - China users still get npm mirror acceleration via `--registry` flag - Uninstall removes both `openclaw` and legacy `@qingchencloud/openclaw-zh` packages to clean up old installations ### Why we need it and why it was done in this way The following tradeoffs were made: - Simplified package management by using a single package for all regions The following alternatives were considered: - N/A ### Breaking changes None. ### Special notes for your reviewer N/A ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A user-guide update was considered and is present (link) or not required. - [ ] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note NONE ``` Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
df4b214295 |
Revert "feat(openclaw): binary download install, auto update check, and gateway refactor (#13165)"
This reverts commit
|
||
|
|
7f3763bae8 |
fix: render xml fenced svg blocks as svg previews (#13431)
Fix #13409 After: <img width="462" alt="CleanShot 2026-03-13 at 10 54 11@2x" src="https://github.com/user-attachments/assets/25c336c4-74c8-4532-9533-30911db93608" /> ```release-note render xml fenced svg blocks as svg previews ``` |
||
|
|
134280a862 |
fix: use i18nKey for error display and add timeout enforcement (#12164)
### What this PR does Before this PR: - Abort/pause-related errors overwrote `message` with raw i18n keys (e.g. `'pause_placeholder'`), losing the original error info for debugging. - Timeout errors (`DOMException` with `name === 'TimeoutError'`) were not distinguished from user-initiated aborts, causing timeouts to display as "Paused" in the UI. - No `AbortSignal.timeout()` enforcement existed in the modern AI SDK path (`parameterBuilder.ts`); `messageThunk.ts` passed `timeout: 30000` in `requestOptions` but it was never used to create an abort signal — effectively dead code. - No localized timeout error message existed. - The timeout constant `defaultTimeout` used camelCase, inconsistent with other exported constants. - The streaming-only behavior of the modern AI SDK path was not documented. After this PR: - Use `i18nKey` field on `SerializedError` (instead of overwriting `message`) for translated error display, preserving original error info for the detail modal. - Rename i18n key `pause_placeholder` → `stream_paused` and extract as a named constant (`ERROR_I18N_KEY_STREAM_PAUSED`). - Add `isTimeoutError()` utility to distinguish `DOMException TimeoutError` from user-initiated `AbortError`, checking both `error` and `error.cause`. - Update `isAbortError()` to explicitly exclude timeout errors. - Add `AbortSignal.timeout(DEFAULT_TIMEOUT)` (10 min) in `parameterBuilder.ts`, combined with the external signal via `AbortSignal.any()`. - Remove the unused `timeout: 30000` from `messageThunk.ts`, establishing `parameterBuilder.ts` as the single timeout control point. - Rename constant `defaultTimeout` → `DEFAULT_TIMEOUT` (SCREAMING_SNAKE_CASE) across all import sites. - Add localized `request_timeout` i18n key (`ERROR_I18N_KEY_REQUEST_TIMEOUT`) for all supported languages. - Add JSDoc to `SerializedError` documenting known dynamic properties (`i18nKey`, `providerId`). - Add documentation notes clarifying the `streamText`-only path in `index_new.ts` and `ApiService.ts`. Fixes # (not applicable; relates to #12016) ### Why we need it and why it was done in this way This PR attempts to address #12016, but per the upstream limitation described in https://github.com/vercel/ai/issues/9655, the root cause is not solvable purely from the client side. The changes here document the streaming-only behavior, improve error handling, and add proper timeout enforcement via `AbortSignal.timeout()`. The following tradeoffs were made: - Keep behavior changes minimal to avoid impacting existing request flows. - Use `i18nKey` field (already supported by `ErrorBlock.tsx` and `ErrorHandlerMiddleware.ts`) instead of overwriting `message` — this preserves original error info for the detail modal while enabling proper i18n display. - Establish `parameterBuilder.ts` as the single timeout control point rather than allowing callers to pass their own timeout values, since no caller currently provides a custom timeout. The following alternatives were considered: - Switching to a non-streaming path (`generateText`), but that is not used in this runtime path and does not address the upstream limitation. - Overwriting `message` with i18n keys (original approach) — rejected because it loses debugging context and creates an implicit contract between producers and consumers. - Adding `i18nKey` as an explicit optional property on `SerializedError` — rejected due to TypeScript's index signature constraint (`string | undefined` is incompatible with `[key: string]: Serializable`); documented via JSDoc instead. Links to places where the discussion took place: https://github.com/vercel/ai/issues/9655 ### Breaking changes None. ### Special notes for your reviewer - This PR is a partial mitigation for #12016; the underlying issue is upstream per the linked Vercel AI SDK issue. - The `i18nKey` pattern on `SerializedError` is already used by `ErrorHandlerMiddleware.ts` for auth/quota errors. This PR extends the same pattern to abort and timeout errors. - `isTimeoutError()` checks both `error` and `error.cause` for `DOMException` with `name === 'TimeoutError'` to handle cases where the AI SDK wraps the original timeout error. - The `timeout: 30000` removed from `messageThunk.ts` was effectively dead code — `parameterBuilder.ts` previously only passed through `requestOptions.signal` but never used `requestOptions.timeout` for abort signal creation. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A user-guide update was considered and is present (link) or not required. ### Release note ```release-note Improve streaming error handling: use i18nKey for localized error display while preserving original error info, add isTimeoutError utility with localized timeout messages, enforce timeout via AbortSignal.timeout() in the modern AI SDK path, and rename pause_placeholder to stream_paused. ``` --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
|
|
ea6b2f83b9 |
fix: resolve single-conversation memory leaks in renderer process (#13113)
### What this PR does Before this PR: Long-running single-conversation agent sessions with many MCP tool calls cause unbounded memory growth in the renderer process (1 GB → 4 GB+), eventually crashing with OOM / white screen. <img width="960" height="607" alt="image" src="https://github.com/user-attachments/assets/e11203a0-5f16-43af-a952-5572c38fb044" /> After this PR: Four previously-leaked resource categories are properly cleaned up during normal operation and on stream abort: 1. **blockUpdateThrottlers LRU** – evicted throttlers now cancel their pending work and associated `requestAnimationFrame` callbacks. 2. **messagePersistThrottlers LRU** – evicted agent-message persist throttlers are cancelled on eviction. 3. **toolPermissions Redux state** – pending tool permission requests are cleared when a stream errors or is aborted. 4. **partialArguments in tool metadata** – the redundant streaming JSON buffer is stripped from completed tool blocks, avoiding duplicate large strings in Redux and IndexedDB. <img width="732" height="831" alt="image" src="https://github.com/user-attachments/assets/15f2383d-b1e5-47b2-b311-2c1545574ab4" /> Fixes #12974 ### Why we need it and why it was done in this way The following tradeoffs were made: - `toolPermissionsActions.clearAll()` is dispatched on every stream error/abort. This is safe because each stream owns its own set of permission requests, and a new stream will create fresh entries. - `partialArguments` is set to `undefined` rather than deleted, since the spread merge makes `delete` ineffective. The following alternatives were considered: - Scoped cleanup per tool call ID instead of `clearAll` for tool permissions. Rejected because the existing `removeByToolCallId` already handles per-call cleanup; the gap was only on abort where all pending requests should be discarded. Links to places where the discussion took place: - Companion PR for multi-conversation fixes: #12975 ### Breaking changes None. ### Special notes for your reviewer This PR is designed to complement #12975 (which addresses multi-conversation leaks like topic cache eviction, abort controller cleanup, and `globalActiveToolCalls` cleanup). There is zero overlap between the two PRs. ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: Write code that humans can understand and Keep it simple - [x] Refactor: You have left the code cleaner than you found it (Boy Scout Rule) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: Not required – internal memory management fix with no user-facing behavior change - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note NONE ``` --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
da10cca0ed |
fix: secure built-in filesystem MCP root handling (#13294)
### What this PR does Before this PR: - The built-in filesystem MCP server accepted absolute paths outside the configured workspace root. - The in-memory filesystem server only read `WORKSPACE_ROOT`, so roots configured via `args` were ignored. - The server registered tool handlers asynchronously, which could cause first-load `mcp:list-tools` failures. - Sensitive filesystem tools could be auto-approved by default. <img width="929" height="641" alt="image" src="https://github.com/user-attachments/assets/1ec4ba6d-f274-40df-a8df-7d9c54e3e8fc" /> After this PR: - Filesystem MCP paths are constrained to the configured workspace root after realpath resolution. - The built-in filesystem server resolves its root from `WORKSPACE_ROOT` or the configured `args`. - Tool handlers are registered before async directory initialization starts. - Built-in filesystem `write`, `edit`, and `delete` require manual approval by default, including a backfill for existing configs. <img width="996" height="667" alt="image" src="https://github.com/user-attachments/assets/44ef44cc-7e50-4244-80b0-ec742df2af0a" /> Fixes #12447 ### Why we need it and why it was done in this way The following tradeoffs were made: - Existing filesystem MCP configurations now default to safer approval behavior for destructive tools. - Path validation resolves symlinks and nearest existing ancestors to block directory escapes for both existing and newly created paths. The following alternatives were considered: - Trusting UI configuration alone without enforcing the root in the filesystem tool layer. - Keeping auto-approve defaults unchanged and relying on users to disable risky tools manually. - Waiting for async initialization to finish before serving requests instead of registering handlers immediately. Links to places where the discussion took place: #12447, #13280 ### Breaking changes The built-in filesystem MCP server now requires manual approval for `write`, `edit`, and `delete` by default. Users who relied on automatic approval for these tools need to re-enable auto-approve explicitly. ### Special notes for your reviewer - This PR does not change Redux state shape or IndexedDB schema. - Added regression coverage for root resolution, path escapes, symlink escapes, and filesystem approval defaults. ### Checklist This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR. Approvers are expected to review this list. - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [x] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [x] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. Check this only when the PR introduces or changes a user-facing feature or behavior. - [x] Self-review: I have reviewed my own code (e.g., via [`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`, or GitHub UI) before requesting review from others ### Release note <!-- Write your release note: 1. Enter your extended release note in the below block. If the PR requires additional action from users switching to the new release, include the string "action required". 2. If no release note is required, just write "NONE". 3. Only include user-facing changes (new features, bug fixes visible to users, UI changes, behavior changes). For CI, maintenance, internal refactoring, build tooling, or other non-user-facing work, write "NONE". --> ```release-note action required: The built-in filesystem MCP server now enforces the configured workspace root and requires manual approval for write, edit, and delete operations by default. ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
d0ce48ee61 |
fix: improve update dialog behavior and prevent unexpected auto-updates (#13363)
### What this PR does
Before this PR:
- When user clicks "Check for Update" and download completes, the update
dialog does not show automatically
- `autoInstallOnAppQuit` was tied to `autoDownload` setting, causing
unexpected auto-updates when app restarts or system shuts down
- Force shutdown during auto-install could corrupt or uninstall the app
- Update installation required user to click through the installer
wizard (Next → Next → Finish)
After this PR:
- Update dialog automatically shows when user manually checks for
updates and download completes
- Background automatic checks won't show the dialog to avoid disturbing
users
- `autoInstallOnAppQuit` is always `false` - users must explicitly click
"Install Now" to trigger update installation
- Update installation is now one-click: clicking "Install Now" will
silently install and auto-restart the app
### Why we need it and why it was done in this way
The following tradeoffs were made:
- Added `manualCheck` field to `UpdateState` to track whether the update
check was triggered by user action
- This allows distinguishing between manual checks (should show dialog)
and automatic background checks (should not disturb user)
The following alternatives were considered:
- Using URL hash check
(`window.location.hash.includes('settings/about')`) - rejected because
user might navigate away during download
- Always showing dialog on download complete - rejected because it would
disturb users during automatic background checks
### Breaking changes
None. This is a behavior improvement that makes updates more
user-friendly and safer.
### Special notes for your reviewer
Four separate commits for related but distinct fixes:
1. `fix: auto show update dialog when user manually checks for updates`
- Shows dialog only for manual checks
2. `fix: disable autoInstallOnAppQuit to prevent unexpected updates` -
Prevents auto-install on app quit
3. `fix: reset manualCheck state on update check completion and error` -
Properly resets state after check
4. `fix: ensure forced installation on quit in quitAndInstall method` -
Uses `quitAndInstall(true, true)` for silent installation with
auto-restart (Windows)
### Checklist
- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [ ] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A user-guide update was considered and is present
(link) or not required. Check this only when the PR introduces or
changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code before requesting review
from others
### Release note
```release-note
fix: Update dialog now automatically shows when user manually checks for updates. Also fixed an issue where the app would unexpectedly auto-update on restart or system shutdown - users must now explicitly click "Install Now" to install updates. On Windows, the update installation is now one-click (silent install with auto-restart).
```
---------
Signed-off-by: kangfenmao <kangfenmao@qq.com>
|
||
|
|
74c0c907b8 |
feat(openclaw): binary download install, auto update check, and gateway refactor (#13165)
### What this PR does Refactors OpenClaw installation to use direct binary downloads instead of npm, adds auto update detection, and delegates gateway lifecycle to OS service manager CLI commands. **Binary download install (replaces npm install):** - Download pre-built binaries from GitHub releases (or gitcode.com mirror for China users) - Install to `~/.cherrystudio/bin/` — no npm/Node.js dependency required - Uninstall by simply deleting the binary file - Detect old npm-installed versions and prompt migration **Auto update check:** - Automatically check for updates via `openclaw update status` when entering the OpenClaw page - Show info alert with version details when an update is available - Perform update via `openclaw update` command (stops gateway first if running) - Version parsing extracted to `services/utils/openClawParsers.ts` with inline snapshot tests **Gateway lifecycle refactor:** - Gateway lifecycle delegated to OS service manager via `openclaw gateway` CLI commands - Removes in-process `ChildProcess` management, `node:net` Socket probing, and `killProcess` helper - Health checks use `openclaw gateway health` CLI command - `getStatus` is now async and probes health to detect externally-started gateways - Return type unified to discriminated union `OperationResult` **Windows-specific handling:** - Skip `gateway install/uninstall` (scheduled task integration has upstream bugs) - Gateway started via `openclaw gateway start --force` - Port conflict detection before startup with clear error messages **UI improvements:** - Auto update alert with "Reinstall" button when new version detected - Copy button on install/uninstall log container and error alerts ### Why we need it and why it was done in this way - Binary download is faster, more reliable, and removes the npm/Node.js dependency for end users - `openclaw update` leverages the tool's built-in update mechanism rather than re-downloading - Delegating to OS service management (launchd/systemd) is more robust — the gateway survives app restarts - Version parsers are pure functions with snapshot tests to prevent regressions ### Breaking changes None. Internal refactoring only — no user-facing API changes. ### Special notes for your reviewer - New IPC channels: `OpenClaw_CheckUpdate`, `OpenClaw_PerformUpdate` - New file: `src/main/services/utils/openClawParsers.ts` (pure parsing functions) - New test: `src/main/services/__tests__/OpenClawService.test.ts` (16 snapshot tests) - i18n: added `openclaw.update.*` and `openclaw.quick_actions.check_update` keys (all locales synced) - Windows: no service registration, gateway started with `--force`, port checked before startup - macOS/Linux: full service lifecycle via CLI commands ### Checklist - [x] PR: The PR description is expressive enough and will help future contributors - [x] Code: [Write code that humans can understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans) and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle) - [x] Refactor: You have [left the code cleaner than you found it (Boy Scout Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html) - [ ] Upgrade: Impact of this change on upgrade flows was considered and addressed if required - [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com) was considered and is present (link) or not required. - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note feat(openclaw): switch to binary download install and add auto update check fix(openclaw): gateway start or stop exception ``` --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: kangfenmao <kangfenmao@qq.com> |