Commit Graph

978 Commits

Author SHA1 Message Date
fullex
fa5bbb7607 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-28 19:38:52 -07:00
SuYao
db8a1834c2 feat(file-manager): unified DirectoryTreeBuilder primitive for Notes (#15363)
### What this PR does

Before this PR:

- Directory loading is split between two pipelines:
`FileStorage.getDirectoryStructure` (Notes) and
`FileStorage.listDirectory` (everything else). Same workspace, two
scans, two watchers.
- `FileStorage.listDirectory` defaults `maxEntries: 20`, silently
truncating list-mode callers (workspace trees rendered `tests/__mocks__`
as a file because it sorted out of the first 20 results).
- Notes' manual chokidar plumbing (`startFileWatcher` / `onFileChange`)
lives on legacy `file-change` IPC and crashes with `EMFILE: too many
open files` on large repos because the watcher opens one FD per
directory in `node_modules`.

After this PR:

- One primitive — `DirectoryTreeBuilder`
(`src/main/file/tree/builder.ts`, RFC §12) — owns the in-memory tree and
the chokidar watcher. It is the only directory-walking code on the main
side.
- Builder dedupe lives behind `TreeRegistry` (lifecycle `WhenReady`):
identical `(rootPath, options)` requests share one builder, with a 500ms
grace window so a remount inside one React commit reuses the warm scan +
watcher instead of paying for a rescan.
- `.gitignore` parsing (via `ignore@7`) drives BOTH ripgrep's
`--ignore-file` AND chokidar's `ignored` predicate, so EMFILE on
`node_modules`-heavy workspaces is gone. `.git` is always excluded even
when `.gitignore` doesn't list it.
- `search.listDirectory` is the now-real Phase 2 entry point (was a
stub). `maxEntries` default raised to `Number.MAX_SAFE_INTEGER`;
truncation is a search-mode concern and callers that want a cap pass it
explicitly. The 20-entry default was the bug.
- Renderer-side `useDirectoryTree(rootPath, options)` hook applies
mutation pushes to a JSON-mirrored `TreeDirRoot`. The tree DTO and
`TreeNode` class live in `packages/shared/file/types/tree.ts` so main
and renderer share one shape (no parent cycles in JSON; WeakMap parent
ref recovered in `FromJSON`).
- Notes (`NotesPage`) migrated off `getDirectoryStructure` + manual
watcher onto `useDirectoryTree` + `useNote` join. The Redux
`starredPaths` / `expandedPaths` path stays untouched in this PR —
`useNote` already covers that surface via `noteTable`.

Fixes #

### Why we need it and why it was done in this way

The following tradeoffs were made:

- **Builder dedupe on main, not renderer.** A renderer-side cache would
still pay one IPC round-trip per remount because the expensive thing is
the FS scan + watcher install, which only the main side owns. Sharing on
the main means one ripgrep + one chokidar regardless of how many panes
mount the same root.
- **500ms grace window for builder teardown.** Long enough to cover
React's "deletions before insertions" effect ordering (sub-millisecond
in practice), short enough that closing a workspace doesn't keep watcher
FDs alive noticeably.
- **`Tree_*` IPC owned by `TreeRegistry.onInit`.** The lifetime of the
handlers must match the lifetime of the chokidar watchers they
reference. Putting them in `FileManager` would leak handlers across
re-init.
- **`TreeNode` class hierarchy (not plain DTOs)** lets `rename` mutate
`path` once at the subtree root and have `adjustChildrenPaths` cascade —
the alternative is rebuilding the subtree, which throws away every
consumer's identity-based caching.
- **Hard ESLint isolation:** `src/main/file/tree/**` does not import
`@main/data/**`. Tree is a runtime concern; persistence is an orthogonal
one (`noteTable` is a sparse state overlay on top of FS paths, not a
tree mirror). RFC §12.6.

The following alternatives were considered:

- Keep the renderer-side cache (rejected — covered above; main-side
dedupe is strictly stronger).
- Add an `excludeGlobs` array option (rejected — the right source of
truth is `.gitignore`, and users editing `.gitignore` get free updates).
- One DTO without classes (rejected — rename cascade is the load-bearing
case).

Links to places where the discussion took place: RFC §12
(`v2-refactor-temp/docs/file-manager/rfc-file-manager.md`)

### Breaking changes

- Removed legacy IPC channels: `File_GetDirectoryStructure`,
`File_StartWatcher`, `File_StopWatcher`, `File_PauseWatcher`,
`File_ResumeWatcher`. Only Notes used them; the migration is in this PR.
No renderer outside Notes touched them.
- `search.listDirectory` (renamed from `FileStorage.listDirectory`) now
defaults to unbounded `maxEntries`. Existing callers that relied on the
implicit 20-cap (none I could find) would need to pass `maxEntries: 20`
explicitly.

### Special notes for your reviewer

- `src/main/file/tree/__tests__/builder.test.ts` covers initial scan,
`.gitignore` honoring, chokidar fan-out, `dispose` cleanup, and JSON
round-trip (no parent cycles).
- `src/main/file/tree/__tests__/registry.test.ts` covers builder dedupe,
grace-window reuse, multi-consumer mutation fan-out, and
`webContents`-destroyed cascade cleanup.
- `src/main/utils/file/__tests__/search.test.ts` locks in the
`maxEntries` default fix and the `--hidden` flag wiring.
- ArtifactPane / chat-page integration of this primitive lives on
`feat/chat-page` and is not part of this PR (that branch has the Shell
forceMount + chat-page Tree IPC integration on top).

### 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
NONE
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:33:48 +08:00
fullex
4439d3b283 chore(app-identity): rebrand bundle id to com.cherryai.CherryStudio
Rename the app bundle id from com.kangfenmao.CherryStudio to
com.cherryai.CherryStudio at every definition point: electron-builder
appId (packaging source of truth), macOS notarization appBundleId,
Windows AppUserModelID, and the selection self-detection allowlist.

Daily preview builds now use com.cherryai.CherryStudio.preview (a distinct
channel id rather than a case-only variant that macOS would treat as the
same app); the workflow replaceAll search strings are updated to the new
id so the preview identity patch keeps matching.

Incidental cleanups bundled in:
- Drop the unused MAIN_VITE_BUNDLE_ID env override; env.d.ts now declares
  the actually-used MAIN_VITE_CHERRYAI_CLIENT_SECRET instead of leaning on
  vite/client's any index signature.
- Remove the stale @kangfenmao/keyv-storage from pnpm.onlyBuiltDependencies.
- SearchService: use @main/core/platform isDev over electron-toolkit is.dev.
2026-05-27 08:31:22 -07:00
亢奋猫
e80b4a4c0b chore: release v1.9.7 (#15362)
### What this PR does

Before this PR:
Version 1.9.6 was the latest release.

After this PR:
Prepares release v1.9.7 with updated version and bilingual release notes
covering 18 commits since v1.9.6.

Fixes #

### Why we need it and why it was done in this way

This is a patch release that includes important bug fixes and new model
support. The changes focus on:

**New Features:**
- Support for grok-build-0.1 capabilities (reasoning, tool use, vision)
- StepFun provider now supports Claude Code / Anthropic-compatible mode
- DeepSeek V4 Flash and MiMo V2.5+ now properly support 1M context
window in Agent mode

**Bug Fixes:**
- Fix ExaMCP web search not returning result content correctly
- Fix code syntax highlighting issues in light theme
- Fix OpenCode launch failures after CLI updates
- Fix Agent mode not forwarding custom provider headers to Claude Code
- Fix Grok 4.3 reasoning effort support in xAI responses
- Improve OpenClaw migration message clarity
- Fix Gemini 3.x models using wrong UI and deprecated parameters
- Fix Qwen max series models incorrectly showing vision capability
- Fix AIHubMix reasoning effort configuration

The following tradeoffs were made:
None — this is a standard patch release with cherry-picked fixes.

The following alternatives were considered:
None — this follows the established release workflow.

Links to places where the discussion took place: N/A

### Breaking changes

None.

### Special notes for the reviewer

This is a release preparation PR. The release notes have been generated
from the 18 commits included in this release, focusing on user-facing
changes as required by the release guidelines.

### 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

```release-note
Cherry Studio 1.9.7 - Model Support & Bug Fixes

 New Features
- [Models] Added support for grok-build-0.1 capabilities (reasoning, tool use, vision)
- [Providers] StepFun now supports Claude Code / Anthropic-compatible mode with auto-filled endpoint
- [Agents] DeepSeek V4 Flash and MiMo V2.5+ now properly support 1M context window in Claude Code

🐛 Bug Fixes
- [Web Search] Fixed ExaMCP web search not returning result content correctly
- [Code Viewer] Fixed code syntax highlighting issues where tokens could disappear in light theme
- [OpenCode] Fixed launch failures after CLI updates by using package-local executable
- [Agents] Fixed Agent mode not forwarding custom provider headers to Claude Code
- [Models] Fixed Grok 4.3 reasoning effort support in xAI responses
- [OpenClaw] Improved migration message clarity when external PATH installation is detected
- [Models] Fixed Gemini 3.x models using wrong UI and sending deprecated sampling parameters
- [Models] Fixed Qwen max series models incorrectly showing vision capability
- [Providers] Fixed AIHubMix reasoning effort configuration not working properly
```

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-27 22:03:55 +08:00
亢奋猫
f43ce3e5de chore(lint): suppress legacy css var warnings in lint scripts (#15216)
Signed-off-by: kangfenmao <kangfenmao@qq.com>
2026-05-20 21:16:54 +08:00
fullex
344c58eb8e feat(job): introduce JobManager + SchedulerService backbone (Phase 1)
cherry-studio v2 had 6+ ad-hoc queue/scheduler implementations (Knowledge,
FileProcessing, agent SchedulerService, TopicQueue, NotificationQueue,
protocol heartbeats) with no shared registry, inconsistent cancel and
progress semantics, and no cross-restart recovery outside agent_task.
This commit lands the unified replacement: JobManager owns Job lifecycle
and SchedulerService owns time-only scheduling, both reusable independently.

Phase 1 ships the backbone only: jobTable + jobScheduleTable, entity
services, 6-state machine with per-handler recovery (abandon/retry/
singleton), catch-up policy (skip-missed/after-startup), retry backoff,
GC, idempotencyKey dedup, useJob renderer hook, and 4 reference docs.
Four-layer lock model addresses libsql client-ts issue #288 (Layer 0
global dispatch mutex serializes all transactions).

croner@^10 is introduced for cron expressions (zero-dep, Electron-friendly).
Application.SHUTDOWN_TIMEOUT_MS is promoted to public for JobManager reuse.
cron-parser stays until Phase 2 agent task migration.

No business migrations in this commit — Knowledge/FileProcessing/agent
SchedulerService remain untouched and migrate in Phase 2-4 per
docs/references/job-and-scheduler/migration-checklist.md.

Follow-ups for Phase 1 completion: DataApi GET /jobs handler, dummy.echo
smoke test, integration tests, migration feasibility report.
2026-05-19 03:57:18 -07:00
Asurada
0b697210bd fix: support Grok 4.3 reasoning effort in xAI responses (#15137)
### What this PR does

Before this PR:

- Grok 4.3 did not fully support reasoning effort through the xAI
responses path.
- Cherry Studio did not expose the Grok 4.3 reasoning options
consistently in model configuration.
- The local @ai-sdk/xai patch could fail pnpm install after manual patch
edits.

After this PR:

- Grok 4.3 correctly maps `reasoning_effort` to xAI responses with
`none`, `low`, `medium`, and `high`.
- The renderer exposes Grok 4.3 as a supported reasoning model with the
correct option set.
- The local @ai-sdk/xai patch is regenerated and narrowed to the
responses path so pnpm install succeeds.

Fixes #

N/A

### Why we need it and why it was done in this way

The following tradeoffs were made:

- The change is scoped to the xAI responses path because Grok is already
routed to `xai-responses` in this repository.
- A local patch is still required because the latest stable
`@ai-sdk/xai` release does not yet support `none` for xAI responses
`reasoningEffort`.
- The patch was narrowed to responses-only to avoid widening behavior
for the base xAI chat path.

The following alternatives were considered:

- Upgrading directly to the latest stable `@ai-sdk/xai`, but the latest
stable release still does not support `none` for responses
`reasoningEffort`.
- Broadening the patch to cover xAI chat options as well, but that would
expand behavior beyond the required Grok 4.3 responses path.

Links to places where the discussion took place: None

### Breaking changes

None.

If this PR introduces breaking changes, please describe the changes and
the impact on users.

### Special notes for your reviewer

- Focused validation passed with `pnpm install`, `pnpm typecheck:web`,
and targeted Vitest suites for xAI/Grok reasoning and model config.
- Full `pnpm test` on Windows still has unrelated baseline failures
outside this change set.

### 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
Fixed Grok 4.3 reasoning effort support in xAI responses so Cherry Studio now correctly exposes and applies the `none`, `low`, `medium`, and `high` reasoning levels.
```

---------

Signed-off-by: ousugo <dkzydkzyxh@gmail.com>
Co-authored-by: ousugo <dkzydkzyxh@gmail.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
2026-05-18 16:24:22 +08:00
fullex
7b556cf786 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-15 05:51:51 -07:00
亢奋猫
a574aa5e3f chore: release v1.9.6 (#15116)
<!-- Template from
https://github.com/kubevirt/kubevirt/blob/main/.github/PULL_REQUEST_TEMPLATE.md?-->
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Consider creating this PR as draft:
https://github.com/CherryHQ/cherry-studio/blob/main/CONTRIBUTING.md
-->

<!--

🚨 Branch Strategy Change (Effective April 3, 2026) 🚨

The `main` branch is now under CODE FREEZE.

- main branch: Only accepts critical bug fixes via `hotfix/*` branches.
Fix PRs must be minimal in scope and must not include any refactoring
code.
- v2 branch: All new features, refactoring, and optimizations should be
submitted to the `v2` branch.

If you are submitting a bug fix to main, please ensure your PR is from a
`hotfix/*` branch.

-->

### What this PR does

Before this PR: Version was 1.9.5

After this PR: Version bumped to 1.9.6 with updated bilingual release
notes

<!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)`
format, will close the issue(s) when PR gets merged)*: -->

Fixes #

### Why we need it and why it was done in this way

This is an automated release preparation for version 1.9.6, containing
bug fixes collected since v1.9.5.

The following tradeoffs were made: None

The following alternatives were considered: None

Links to places where the discussion took place: N/A

### Breaking changes

None

### Special notes for your reviewer

**Review Checklist:**
- [ ] Review generated release notes in `electron-builder.yml`
- [ ] Verify version bump in `package.json`
- [ ] CI passes
- [ ] Merge to trigger release build

**Release Summary (English):**
- [AI] Fixed crash when chat model's stored provider no longer exists
- [AI] Fixed streaming requests aborted after 30 minutes during active
data transfer (affected models with extended thinking)
- [Agents] Fixed agent session creation failures when provider settings
change
- [Agents] Fixed deepseek-r1 models incorrectly showing function_calling
label causing errors in Agent mode
- [Agents] Use task name instead of agent name for cron task sessions
- [MCP] Fixed approval card not auto-expanding to show Run/Cancel
buttons
- [MCP] Clean up OAuth tokens when deleting servers
- [Code Tools] Fixed Codex CLI launch failure when using OpenAI or other
reserved providers
- [Claude Code] Fixed launch failures caused by auth conflicts with
provider environment variables
- [Image] Fixed gpt-image-2 multi-turn editing crash
- [Knowledge] Fixed HTTP/HTTPS/FTP URLs being stripped from Markdown
documents
- [OpenMinerU] Fixed preprocessing ENOENT errors due to ZIP structure
change
- [Qiniu] Fixed PDF upload regression for GPT-5.4 models

### 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.

- [ ] PR: The PR description is expressive enough and will help future
contributors
- [ ] 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)
- [ ] 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.
- [ ] 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
Cherry Studio 1.9.6 - Bug Fixes

🐛 Bug Fixes
- [AI] Fixed crash when chat model's stored provider no longer exists
- [AI] Fixed streaming requests aborted after 30 minutes during active data transfer (affected models with extended thinking)
- [Agents] Fixed agent session creation failures when provider settings change
- [Agents] Fixed deepseek-r1 models incorrectly showing function_calling label causing errors in Agent mode
- [Agents] Use task name instead of agent name for cron task sessions
- [MCP] Fixed approval card not auto-expanding to show Run/Cancel buttons
- [MCP] Clean up OAuth tokens when deleting servers
- [Code Tools] Fixed Codex CLI launch failure when using OpenAI or other reserved providers
- [Claude Code] Fixed launch failures caused by auth conflicts with provider environment variables
- [Image] Fixed gpt-image-2 multi-turn editing crash
- [Knowledge] Fixed HTTP/HTTPS/FTP URLs being stripped from Markdown documents
- [OpenMinerU] Fixed preprocessing ENOENT errors due to ZIP structure change
- [Qiniu] Fixed PDF upload regression for GPT-5.4 models
```

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-15 19:45:51 +08:00
Phantom
d2c568e349 feat(file): Add schema and foundation for new file module (#13451)
### What this PR does

Adds the **Phase 1a contract surface** for the file module — types, DB
schema, DataApi + File IPC contracts, FileManager skeleton, and
architecture docs.

**Phase 1b.1 (Read Path & Repository), 1b.2 (Write Path & Lifecycle),
1b.3 (Watcher & DanglingCache), and 1b.4 (OrphanSweep &
FileRefCheckerRegistry) are now all landed on top of 1a in this same
PR.** This is the complete Phase 1b runtime — reviewers see the full
read + write + watcher + orphan-sweep picture in one place.

Design, contracts, and decision rationale live in the architecture docs:

-
[`docs/references/file/architecture.md`](docs/references/file/architecture.md)
— module boundaries, type system, IPC/DataApi contracts, layered
architecture, service lifecycle, mutation propagation
-
[`docs/references/file/file-manager-architecture.md`](docs/references/file/file-manager-architecture.md)
— FileManager internals (storage, version detection, atomic writes,
reference cleanup, DirectoryWatcher, orphan sweep, DanglingCache state
machine, key design decisions)

#### Phase 1a deliverables

- Types (`FileEntry` / `FileInfo` / `FileHandle` /
`CanonicalExternalPath` brand)
- DB schema (`file_entry` + `file_ref`) with per-origin CHECK
constraints
- DataApi schemas + stub handlers
- File IPC contract (polymorphic `FileHandle` dispatch;
`batchGetMetadata` included)
- FileManager skeleton + `internal/*` + `ops/*` + `watcher/` +
`DanglingCache` + `versionCache`
- Mutation propagation design (three typed events + prefix-based
queryKey invalidation)

#### Phase 1b.1 deliverables (read-path runtime)

- Shared utilities: `getFileTypeByExt`, `sanitizeFilename`,
`validateFileName` extracted to `@shared/file/types`
- Path utilities: `canonicalizeExternalPath` (NFC + null-byte guard +
trailing-sep strip), `isPathInside`, `isUnderInternalStorage`,
`canWrite`
- FS read primitives: `stat`, `exists`, `read` (text/base64/binary
overloads), `hash` (initial MD5; swapped to xxhash-h64 in 1b.2)
- Metadata utilities: `getFileType(path)`, `isTextFile`, `mimeToExt`
- Repositories: `FileEntryService` + `FileRefService` read methods
(Drizzle-backed, Zod-branded outputs)
- Pure-function modules: `internal/content/{read,hash}`,
`internal/dispatch.ts` (FileHandle dispatcher)
- `toFileInfo(entry)` projection
- `FileManager` class as `BaseService` (`@Injectable('FileManager')`
`@ServicePhase(WhenReady)`); read methods only
- `DanglingCache` + `VersionCache` minimal viable singletons (full impls
in 1b.3 / 1b.2)
- DataApi `/files/*` read handlers fully implemented (entries / single /
ref-counts / refs-by-source)
- 60+ TDD tests (unit + boundary + setupTestDatabase integration)

#### Phase 1b.2 deliverables (write-path runtime)

- **FS atomic primitives** (open to non-file-module consumers per
architecture §5.3): `atomicWriteFile` (tmp + fsync + rename +
fsync(dir)), `atomicWriteIfUnchanged` (re-stat OCC + content-hash
fallback for second-precision mtime), `createAtomicWriteStream`
(Writable wrapper, abort/destroy unlinks tmp)
- **FS general primitives**: `write` (delegates to atomicWriteFile),
`copy` (atomic dest), `move` (rename + EXDEV → copy+unlink fallback),
`remove` (idempotent ENOENT), `mkdir` / `ensureDir` / `removeDir`,
`download` (fetch → atomic stream)
- **Hash swap**: `hash()` migrated MD5 → `xxhash-wasm` h64 streaming;
legacy `md5` dep retained for KnowledgeService loaders
- **VersionCache LRU**: capacity-bounded (default 2000) with
re-insert-on-touch recency
- **Repository mutations**: `FileEntryService.create/update/delete`
(auto UUIDv7 default id, raw DB CHECK errors propagate);
`FileRefService.create/createMany/cleanupBySource/cleanupBySourceBatch`
(`onConflictDoNothing` for batch upsert)
- **internal/entry/**: `create.createInternal` (4 source variants: bytes
/ base64 / path / url) + `create.ensureExternal` (canonicalize + stat +
idempotent upsert + duplicate-suspect peer warn);
`lifecycle.trash/restore/permanentDelete` + batch variants (DB+FS
decoupled, internal best-effort unlink); `rename` (internal DB-only,
external fs.move + canonical externalPath); `copy` (pipes through
createInternal with rollback)
- **internal/content/write.ts**: `write` / `writeIfUnchanged`
(cache-not-trusted re-stat OCC, `StaleVersionError` rewrap from
`PathStaleVersionError`) / `createWriteStream` / `*ByPath` variants
- **internal/system/**: `shell.open` / `shell.showInFolder` (electron
`shell` wrappers); `tempCopy.withTempCopy` (isolated tmp dir; cleanup on
throw)
- **FileManager facade**: every IFileManager mutation method now
delegates to its `internal/*` counterpart (`createInternalEntry` /
`ensureExternalEntry` / `batchCreate*` / `batchEnsure*` / `write` /
`writeIfUnchanged` / `createWriteStream` / `createReadStream` / `trash`
/ `restore` / `permanentDelete` + batch / `rename` / `copy` /
`withTempCopy` / `open` / `showInFolder`); no method throws
notImplemented anymore
- ~60 new TDD tests (each behavior unit = one RED→GREEN→REFACTOR
commit); end-to-end integration scenarios via `setupTestDatabase` cover
atomic-rollback zero-residue, OCC second-precision-mtime
no-false-positive, trash-external CHECK enforcement, full
create→write→read→trash→restore→permanentDelete round-trip, and external
permanentDelete-leaves-user-file-untouched

#### Phase 1b.3 deliverables (watcher + DanglingCache observability)

- **DanglingCache class** (replaces 1a const-literal skeleton):
`byEntryId: Map<entryId, CachedState>` + `pathToEntryIds:
Map<canonicalPath, Set<entryId>>` reverse index, lazy TTL expiration
(default 30 min per architecture §11.2), `forceRecheck` escape hatch,
`Emitter<DanglingStateChangedEvent>` firing only on genuine state
transitions (same-state observations are silent). Injectable `now` /
`statProbe` / `ttlMs` / `fileEntryService` seams for deterministic
tests.
- **createDirectoryWatcher** chokidar v4 wrapper: `add` / `unlink` /
`change` / `ready` / `error` events; built-in OS-junk basename ignores
(`.DS_Store` / `.localized` / `Thumbs.db` / `desktop.ini`); idempotent
`close()`. Factory auto-wires `add` →
`danglingCache.onFsEvent(path,'present')` and `unlink` → `'missing'`.
(Architecture §8.2's richer `onAddDir`/`onUnlinkDir`/`onRename` events
deferred — no consumer needs them in scope.)
- **Reverse-index maintenance from mutation flows**: `ensureExternal`
calls `addEntry` + `onFsEvent('present','ops')` on insert (no-op on
reuse); `permanentDelete(external)` calls `removeEntry`;
`rename(external)` swaps `removeEntry(oldPath) + addEntry(newPath) +
onFsEvent(newPath,'present','ops')`.
- **FileManager surface**: `getDanglingState({id})` (internal →
'present', external → cache check, unknown id → 'unknown');
`batchGetDanglingStates({ids})` (parallel fan-out, unknown ids mapped to
'unknown'); `subscribeDangling({id}, listener)` (in-process per-entry
filter; renderer fan-out via `file-manager-event` IPC channel deferred
to Phase 2).
- **FileManager.onInit**: awaits `danglingCache.initFromDb()` (populates
reverse index from non-trashed external entries; no startup stat probe
per architecture §10.6); registers `File_GetDanglingState` /
`File_BatchGetDanglingStates` IPC handlers via `this.ipcHandle`
(auto-disposed on stop).
- New `IpcChannel` constants: `File_GetDanglingState`,
`File_BatchGetDanglingStates`.
- ~30 new TDD tests across DanglingCache (18 unit) + watcher (6 real-FS)
+ FileManager integration (INT-7..INT-10).

#### Phase 1b.4 deliverables (orphan sweep + FileRefCheckerRegistry)

- **FileRefCheckerRegistry**: `Record<FileRefSourceType,
SourceTypeChecker<...>>` typed registry forces exhaustive coverage at
compile time — adding a new variant to `FileRefSourceType` without a
checker triggers a TS build error. Phase 1 ships `FileRefSourceType =
'temp_session' | 'knowledge_item'`: real DB-backed checker for
`knowledge_item` (Drizzle `inArray` against `knowledge_item`);
`temp_session` checker treats every sourceId as gone (sessions are
in-memory only). `chat_message` / `painting` / `note` are **deliberately
not in the union yet** — each will be added in lockstep (tuple entry in
`allSourceTypes` + `createRefSchema` variant + `SourceTypeChecker`) by
the PR that migrates the owning domain's DB tables to v2. Stray writes
during the migration window fail fast at `FileRefSchema.parse` rather
than being silently persisted under a no-op stub.
- **OrphanRefScanner** (RFC §6.4): `scanOneType(sourceType)` enumerates
distinct `file_ref.sourceId` per type, asks the checker which are alive,
deletes the rest via `cleanupBySourceBatch`. `scanAll()` aggregates
across every registered sourceType. Backed by new
`FileRefService.listDistinctSourceIds` to keep all SQL inside the repo.
- **Report-only orphan-entry pass** (architecture §7.1 default policy is
"preserve"): `scanOrphanEntries` groups active entries with zero
`file_ref` rows by origin. **No deletion** — surfaced via
`getOrphanReport()` for the cleanup-UI consumer. Backed by new
`FileEntryService.findUnreferenced` LEFT JOIN-based query.
- **Startup file sweep** (architecture §10): `runStartupFileSweep`
snapshots `file_entry.id` (active + trashed) into a `Set` via new
`FileEntryService.listAllIds`, walks `{userData}/files/`, plans unlink
for (a) UUID-named files whose id is not in the snapshot and (b)
`*.tmp-<UUID>` atomic-write residue. Applies the `mtime > 5min`
freshness gate (§10.3) — files newer than that are presumed in-flight
and preserved. Plan-then-execute with the `50% / 20-count-floor /
10MB-floor` safety threshold (§10.4); aborts emit
`abortReason='count-fraction'|'byte-fraction'`. Single structured
`orphan-file-sweep` log per run (info / warn / error per outcome,
§10.5).
- **DB-sweep umbrella + observability** (`runDbSweep`): runs scanAll +
scanOrphanEntries, emits one `orphan-sweep` structured record
summarising both passes; failure path returns `outcome='failed'` +
`errorMessage` so callers don't throw on background fire-and-forget.
- **FileManager integration**: `onInit` schedules a fire-and-forget
`runStartupSweeps` that runs the FS-level + DB-level sweeps in parallel;
failures of either are logged but never block ready. `getOrphanReport()`
exposes the most recent `DbSweepReport` (orphan-ref counts already
cleaned + orphan-entry counts preserved) + `lastRunAt` for the cleanup
UI surface.
- ~30 new TDD tests across registry (14 unit) + orphan sweep (16 unit +
integration) + FileManager integration (INT-11/INT-12) + repo
(`findUnreferenced`, `listAllIds`, `listDistinctSourceIds`).

**Out of scope (deferred to Phase 2)**:
- Architecture §7.2 dangling-external auto-cleanup (external + missing +
0-ref + >30d retention) — narrow extension shipping with the cleanup UI.
- Adding `chat_message` / `painting` / `note` as `FileRefSourceType`
variants (tuple entry + schema + checker added together) — gated on each
domain's v2 batch migration.
- Cleanup-UI surface that consumes `getOrphanReport()` — Phase 2
renderer work.

Renderer-side File IPC bridge for write/dangling methods stays deferred
to Phase 2 alongside the consumer-batch migrations. The Phase 1b runtime
is consumable from main-side business services through
`application.get('FileManager')`.

### Why we need it and why it was done in this way

Contract-first concentrates design review in one place; Phase 1b.x then
becomes pure "honor the contracts". Each 1b.x phase keeps strict TDD
(RED → GREEN → REFACTOR per behavior, ~one commit per cycle); each phase
ends with a verification gate (push → CI green) before the next phase
begins.

Core decisions (origin two-state, `FileEntry`/`FileInfo` split, DataApi
SQL-only, external `permanentDelete` DB-only, TTL `DanglingCache`, OCC
trust boundary, atomic write fsync default, etc.) and their rationale
are recorded in `file-manager-architecture.md §12 Key Design Decisions`
— not duplicated here.

### Breaking changes

None — purely additive (read+write paths are new, no existing callers
replaced yet).

### Special notes for your reviewer

- Review focus: contracts (1a) + read-path runtime (1b.1) + write-path
runtime (1b.2) + watcher/DanglingCache (1b.3) + orphan sweep / registry
(1b.4). Phase 1b is now complete on this branch.
- **Phase 1a contract stability policy** (architecture.md top) is
binding — any 1b.x PR that finds a contract mismatch PRs the doc
revision first.
- Deferred (Phase 2): renderer-side File IPC bridge for
write/dangling/orphan methods (alongside consumer migration); cleanup-UI
surface consuming `getOrphanReport()`; architecture §7.2
dangling-external auto-cleanup (>30d retention); adding `chat_message` /
`painting` / `note` as `FileRefSourceType` variants (each adds tuple
entry + schema + checker in lockstep, gated on the owning domain's v2
batch migration); DanglingCache periodic snapshot logger (architecture
§11.8); `listDirectory` ripgrep wrapper; `compressImage`
(KnowledgeService consumer); FileUploadService + `file_upload` table
(Vercel AI SDK Files API).

### 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: N/A — purely additive
- [ ] Documentation: Internal architecture docs included
(`docs/references/file/`); no user-facing docs change
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
NONE
```

---------

Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-05-13 16:06:10 +08:00
Qin Lingguang
72bb96ed71 fix(knowledge): preserve HTTP URLs in knowledge base documents (#14983)
### What this PR does

Before this PR:

When adding Markdown documents to a knowledge base, all HTTP/HTTPS/FTP
URLs are silently stripped from the indexed content. Searching the
knowledge base returns text with all links removed.

After this PR:

URLs in knowledge base documents are preserved in the indexed chunks, so
searches return the full original content including links.

Fixes #14956 #14962

### Why we need it and why it was done in this way

**Root cause:** The `@cherrystudio/embedjs-loader-web` package (forked
from upstream `@llm-tools/embedjs`) contains a regex in `WebLoader` that
unconditionally strips all URLs from text content:

```js
.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '')
```

This was originally designed for web scraping — removing noisy
navigation/footer URLs when crawling web pages. In the upstream's
primary use case (crawling web pages for RAG), this is reasonable
behavior since navigation bars, footers, and sidebars produce many
irrelevant URLs that add noise to embeddings. So this is not a bug in
the upstream library — it's a difference in usage context. Cherry Studio
uses these loaders for user-provided Markdown documents where URLs are
intentional, meaningful content authored by the user.

However, `MarkdownLoader` delegates to `WebLoader` (Markdown → HTML via
micromark → WebLoader), so Markdown file URLs get caught by the same
regex and removed.

The `CherryHQ/embed-js` fork inherited this behavior as-is from upstream
`@llm-tools/embedjs` — the fork only changed the `@llm-tools/` namespace
to `@cherrystudio/` with no functional modifications to the loader
logic.

**Why pnpm patch instead of fixing the fork repo:**

1. This is not an upstream bug but a usage context mismatch — submitting
an upstream PR to change this behavior could break the upstream's
intended web-scraping use case.
2. The `CherryHQ/embed-js` fork periodically syncs with upstream (e.g.,
`chore: sync to upstream` commits), so any fork-side change would be
overwritten on next sync.
3. The fork has been intentionally kept minimal — only namespace renames
— to make syncing straightforward.
4. Using `pnpm patch` is consistent with the project's existing pattern
(22+ patches already in `patches/`).

The following alternatives were considered:

- Fixing the `CherryHQ/embed-js` fork directly — rejected due to the
sync-overwrite risk described above.
- Adding a `keepUrls` constructor option to `WebLoader` — rejected as
more invasive than needed for a hotfix.

### Breaking changes

None. The only behavior change is that URLs are now preserved in
knowledge base chunks instead of being silently removed. This is the
expected/correct behavior.

### Special notes for your reviewer

- The patch removes the URL-stripping regex from both `web-loader.js`
(ESM) and `web-loader.cjs` (CommonJS).
- The `MarkdownLoader` bracket-stripping regex (`[[\](){}]`) is a
separate cosmetic issue not addressed in this hotfix — with URLs
preserved, `text [https://url]` becomes `text https://url` after bracket
stripping, so the URL itself is intact.
- Users who have already added Markdown files to their knowledge base
will need to re-index those files to get URLs in the indexed content.

### 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
Fixed a bug where all HTTP/HTTPS/FTP URLs were stripped from Markdown documents when adding them to a knowledge base, causing search results to lose all links.
```

---------

Signed-off-by: raymond <13162938362@163.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
2026-05-12 22:51:38 +08:00
亢奋猫
29a3750ac3 chore(style-reminders): add Tailwind canonical checks (#14862)
### What this PR does

Before this PR:

Tailwind canonical class suggestions such as `w-[420px] -> w-105` had to
be fixed manually, and the PR style reminder workflow only reported
newly introduced legacy renderer CSS variables.

After this PR:

Adds `pnpm styles:canonical <path>` to rewrite static Tailwind class
strings to their canonical Tailwind v4 forms. The PR style reminders
workflow now comments on both newly introduced legacy CSS variables and
Tailwind canonical class suggestions.

<!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)`
format, will close the issue(s) when PR gets merged)*: -->

Fixes #

### Why we need it and why it was done in this way

The following tradeoffs were made:

The canonical class fixer is conservative: it only rewrites static JSX
`class` / `className` strings and static `cn(...)` string inputs,
leaving dynamic template literals untouched. It uses Tailwind's own
design system canonicalization instead of maintaining a manual mapping
table.

The following alternatives were considered:

A regex-only implementation was avoided because Tailwind
canonicalization depends on Tailwind v4 parsing and theme behavior. A
separate PR workflow comment was also avoided so the style reminders
comment remains the single bot comment.

Links to places where the discussion took place: N/A

### Breaking changes

None.

### Special notes for your reviewer

Compatibility aliases and legacy marker/env fallback were removed; the
PR workflow now uses the `style-reminders` script, marker, and output
naming.

Validation performed:

- `pnpm test:scripts --
scripts/__tests__/check-pr-style-reminders.test.ts
scripts/__tests__/fix-tailwind-canonical-classes.test.ts`
- `pnpm build:check`
- `git diff --check`

### 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
- [ ] 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
NONE
```

---------

Signed-off-by: kangfenmao <kangfenmao@qq.com>
2026-05-11 14:48:55 +08:00
亢奋猫
fa2ac478d3 chore: release v1.9.5 (#14963)
### What this PR does

Before this PR:
- Version was 1.9.4
- Release notes were outdated

After this PR:
- Version bumped to 1.9.5
- Bilingual release notes updated with all changes since 1.9.4

This release includes 23 commits addressing bug fixes, improvements, and
one new feature across multiple components including search, backup,
models, agents, and more.

### Breaking changes

None. This is a patch release with backward-compatible bug fixes and
improvements.

### Special notes for your reviewer

- Review generated release notes in `electron-builder.yml`
- Verify version bump in `package.json`
- CI passes
- Merge to trigger release build

### Release note

```release-note
Cherry Studio 1.9.5 - Bug Fixes & Improvements

🐛 Bug Fixes
- [Search] Fixed built-in web search truncating assistant responses when web search was the only active tool
- [Messages] Fixed outer scrolling issue in horizontal multi-model layout
- [Backup] Fixed app hanging during restore when selection helper was enabled
- [Backup] Fixed silent data loss when restoring v6 .zip backups on macOS/Linux
- [Models] Fixed CherryIN OpenAI-protocol models not appearing in Agent model picker
- [Models] Fixed DeepSeek V4 model slugs not being detected for reasoning effort
- [Models] Fixed Tongyi model icon matching
- [Models] Fixed Claude Opus 4.7 support
- [Image] Fixed generated image re-editing in NewApiPage
- [Code Tools] Disabled opencode built-in auto-update check
- [API Server] Fixed trailing /v1 stripping from Anthropic SDK baseURL
- [Gateway] Fixed Vercel AI Gateway model list fetch

💄 Improvements
- [Agents] Show all sessions and agents in sidebar instead of capping at 20
- [Agents] Removed stale mcp__browser__* references from agent prompt
- [Models] Updated DeepSeek provider defaults to use V4 model IDs
- [Models] Added support for hosted Gemma 4 thinking mode
- [Feishu] Use emoji reaction as typing indicator
- [i18n] Fixed default assistant and topic names not updating on language switch
- [Vertex] Improved model list fetch and service account setup
- [Reasoning] Added enable_thinking param for SiliconFlow DeepSeek/Zhipu models
- [Claw] Added timeout_minutes parameter to cron tool

 New Features
- [Painting] Added gpt-image-2 support to AiHubMix provider
```

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-11 13:21:35 +08:00
亢奋猫
dee3bb0928 feat(settings): refactor settings UI and add settings window (#14567)
Signed-off-by: kangfenmao <kangfenmao@qq.com>
Signed-off-by: jdzhang <625013594@qq.com>
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-05-08 18:09:26 +08:00
fullex
16f120bdd3 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-08 00:27:46 -07:00
SuYao
1f867749b8 fix(anthropic): support Claude Opus 4.7 (#14349)
### What this PR does

Before this PR:
- Selecting Claude Opus 4.7 (`claude-opus-4-7`) in Cherry Studio could
not work:
- The model is not in the catalog, so users could only add it manually
as a custom model.
- With reasoning enabled, Cherry would send `effort: 'max'` (4.6
mapping) instead of the native `xhigh` that 4.7 supports, and
`thinking.display` would default to `omitted` — stripping reasoning text
from the response and breaking Cherry's thinking UI.
- Temperature and top_p were still sent when `reasoning_effort` was
`default` or `none`, which Opus 4.7 rejects with HTTP 400 regardless of
reasoning settings.
- `getMaxTokens` subtracted a thinking budget for 4.6 / 4.7 (both use
adaptive thinking and do not send `budgetTokens`), incorrectly shrinking
`max_tokens`.

After this PR:
- `claude-opus-4-7` is catalogued under the Anthropic provider with a
128K output-token limit, routed through the existing `claude46`
reasoning-effort type so it shares the `[low, medium, high, xhigh]`
option list.
- Opus 4.7 sends native `xhigh` to Anthropic (Opus 4.6 still sends
`max`). Bedrock continues to map `xhigh → 'max'` until
`@ai-sdk/amazon-bedrock` adds `xhigh`.
- Adaptive thinking defaults to `display: 'summarized'` on Opus 4.7, so
reasoning text continues to stream back for Cherry's UI.
- `temperature` and `top_p` are dropped unconditionally for Opus 4.7 in
`getTemperature` / `getTopP`.
- `getMaxTokens` skips the budget subtraction for both 4.6 and 4.7
(shared adaptive-thinking path).
- At the agent-session dispatch site, `effort: 'xhigh'` is mapped to
`'max'` and the `display` field is stripped before reaching the Claude
Agent SDK (whose types do not yet include them).

Fixes #

### Why we need it and why it was done in this way

The following tradeoffs were made:
- Opus 4.7 shares the `claude46` thinking model type (same effort
options) instead of introducing a new `claude47` enum member. This
avoids churn in `ThinkingModelType` / `MODEL_SUPPORTED_OPTIONS`, and the
provider-boundary mapping (xhigh → native on 4.7, xhigh → max on 4.6)
cleanly expresses the only real difference.
- `thinking.display` is defaulted to `'summarized'` so existing Cherry
behavior (reasoning text streamed to the UI) is preserved. The Anthropic
API default is `'omitted'`, which would silently remove reasoning
content.
- `getMaxTokens` fix for 4.6 is applied alongside 4.7 because the same
code path is touched. This is in scope for the hotfix — the 4.7 path
cannot work correctly without it.
- The agent-session call site performs a local narrowing (`xhigh →
'max'`, strip `display`) rather than extending `AgentEffort` /
`AgentThinkingConfig` schemas. This keeps the change small and
compatible with the currently installed `@anthropic-ai/claude-agent-sdk`
type shape.

The following alternatives were considered:
- Introducing a new `claude47` `ThinkingModelType` variant and dedicated
option lists. Rejected — the effort list is identical to 4.6; a new
variant would duplicate data without adding behavior.
- Wiring `taskBudget` support (the agentic-workflow token budget
introduced in the same Vercel AI SDK PR). Intentionally out of scope —
Cherry has no UI or call site that would supply one, and it is not a
hotfix-class concern.
- Extending `AgentEffortSchema` and `AgentThinkingConfigSchema`
end-to-end. Rejected — the Claude Agent SDK still types `effort` as
`'low' | 'medium' | 'high' | 'max'` and `ThinkingAdaptive` as `{ type:
'adaptive' }`, so the schema widening would have to be undone at the SDK
boundary anyway.

Links to places where the discussion took place:
https://github.com/vercel/ai/pull/14529

### Breaking changes

None. Existing Claude 4.6 and earlier Claude models are unchanged.

### Special notes for your reviewer

- Targeted at `main` as a hotfix per the code-freeze policy. The same
fix should probably land on `v2` as well after this merges, but that is
a separate PR.
- `@ai-sdk/anthropic` is bumped to `^3.0.71` (minimum version that
exposes the Opus 4.7 / `xhigh` / `display` / `taskBudget` types). The
lockfile resolves to `3.0.71`. No other `@ai-sdk/*` packages are
touched.
- Added tests:
- `src/renderer/src/config/models/__tests__/utils.test.ts` —
`isClaude47SeriesModel` detection across direct API / Bedrock / Vertex
formats.
- `src/renderer/src/config/models/__tests__/reasoning.test.ts` —
`findTokenLimit` returns 128K for 4.7, and `getThinkModelType` routes
4.7 to `claude46`.
- `src/renderer/src/aiCore/utils/__tests__/reasoning.test.ts` —
`getAnthropicReasoningParams` returns `{ thinking: { type: 'adaptive',
display: 'summarized' }, effort: 'xhigh' }` for Opus 4.7 + xhigh, and
the `display` field is present even when no effort is set.
-
`src/renderer/src/aiCore/prepareParams/__tests__/model-parameters.test.ts`
— `getTemperature` / `getTopP` return `undefined` for Opus 4.7
regardless of reasoning settings.
- `pnpm lint` and `pnpm test` pass locally (3488 passed | 72 skipped).
One pre-existing Shiki tokenizer test is flaky under full-suite ordering
but passes in isolation and on clean `main`; unrelated to this change.

### 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

```release-note
Add support for Claude Opus 4.7 (`claude-opus-4-7`), including native `xhigh` reasoning effort, adaptive thinking with summarized display (so reasoning text continues to stream to the UI), and the new API requirement that `temperature` / `top_p` be omitted.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
2026-05-07 13:27:56 +08:00
fullex
1afd70b372 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-03 00:11:34 -07:00
fullex
750b867a60 chore(v2-refactor): set 2.0.0-dev and document v1 coexistence mindset
Reset version to 2.0.0-dev to reflect this branch is internal-only and
not user-facing, and add a Coexistence Mindset section to CLAUDE.md so
AI agents stop writing defensive code for two throwaway things:

- v1 code and data (Redux, Dexie, ElectronStore) — all v1 code is
  deleted before v2 ships; v1 data reaches v2 only via migrators in
  src/main/data/migration/v2/.
- Drizzle schemas and migrations/sqlite-drizzle/*.sql — rewritten
  freely until release, then wiped and regenerated as a single clean
  initial migration. Only the final regenerated migration is the
  correctness target.

Also extend the Data Layer "Removing" list with ElectronStore so the
v1 boundary referenced by the new section is canonical.
2026-05-01 05:39:39 -07:00
SuYao
06f93a0d2f fix(deps): bump @ai-sdk/deepseek to 2.0.30 (#14718)
### What this PR does

Before this PR:

- `@ai-sdk/deepseek` was pinned to `2.0.29`, missing an upstream fix for
`deepseek-v4` reasoning content in multi-turn conversations.

After this PR:

- Bumps `@ai-sdk/deepseek` from `2.0.29` to `2.0.30` (latest stable).
- Renames the local patch file to `@ai-sdk__deepseek@2.0.30.patch` and
updates the `pnpm.patchedDependencies` key. The patch (which adds the
`reasoning_effort` option for `high`/`max`) re-applies cleanly because
the patched regions are unchanged in `2.0.30`.

Fixes #

### Why we need it and why it was done in this way

Upstream `2.0.30` ships a single fix from vercel/ai commit `0498012`:
`fix(provider/deepseek): preserve reasoning_content for deepseek-v4 in
multi-turn requests`. It threads the `modelId` into
`convertToDeepSeekChatMessages`, stops dropping `reasoning` blocks
before the last user message for `deepseek-v4`, and ensures
`reasoning_content` is at least `""` rather than `undefined` so the
field is preserved across turns. Keeping the local patch in sync with
upstream prevents drift and unblocks future DeepSeek model rollouts.

The following tradeoffs were made:

- Patch file content is byte-identical; only the filename and
`pnpm.patchedDependencies` key are updated. This avoids gratuitous diff
churn while keeping the patch addressable to the new version.

The following alternatives were considered:

- Wait for a larger DeepSeek change before bumping — rejected; the
upstream fix is small, isolated, and there is no reason to delay.
- Move to `3.0.0-beta.x` — rejected; betas track AI SDK v6 and are out
of scope for the `main` branch hotfix lane.

Links to places where the discussion took place: N/A

### Breaking changes

None. Public API surface, exported types, and the `reasoning_effort`
patch behavior are unchanged.

### Special notes for your reviewer

- Verified the patch applied to `2.0.30` in `node_modules` — both the
local addition (`reasoning_effort`) and the upstream fix
(`isDeepSeekV4`) are present after `pnpm install`.
- `pnpm build:check` passes locally (4199 tests, 0 errors).
- This change is restricted to `main` per the code-freeze policy and is
delivered from a `hotfix/*` branch with no refactoring.

### 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: suyao <sy20010504@gmail.com>
2026-04-30 14:17:43 +08:00
fullex
6a6b47562b Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-29 20:32:41 -07:00
亢奋猫
c813320bfc chore: release v1.9.4 (#14681)
### What this PR does

This is the release PR for Cherry Studio v1.9.4, a patch release that
includes bug fixes and new model support.

**Changes included in this release:**
- 12 commits since v1.9.3
- Version bump to 1.9.4
- Updated release notes in electron-builder.yml

### Release Notes

**English:**
Cherry Studio 1.9.4 - Bug Fixes & Model Support

🐛 Bug Fixes
- [OpenCode] NEWAPI provider models now appear in the dropdown and route
correctly
- [Image Generation] Fixed gpt-image-2/gpt-image-1.5 editing and
generation across multiple providers
- [Models] Fixed Kimi K2.6 requests being rejected due to unsupported
temperature settings
- [Gateway] Fixed Vercel AI Gateway model list fetch failing due to
missing authentication
- [Copilot] Fixed GitHub Copilot model synchronization

 New Features
- [Models] Added MiMo V2.5 model support with reasoning and calling
capabilities
- [Models] Added DeepSeek V4+ model support with reasoning effort
control (high/max)
- [Models] Mistral Small 4 now supports vision and adjustable reasoning
effort

💄 Improvements
- [Agents] Removed auto-injected @cherry/browser MCP (re-enable manually
if needed)

### Commits Included

b834886d ci(v2-preview): add daily preview build
8b9f8f7b fix(code-tools): support new-api providers and endpoint type
routing for OpenCode (#14511)
9a213eaa fix(gateway): pass user apiKey to createGateway when fetching
models (#14605)
26d877e0 hotfix(image-generation): fix gpt-image-2 / gpt-image-1.5
failures and stuck pending placeholder (#14578)
8ed7c075 hotfix(agents): drop @cherry/browser MCP auto-injection
(#14571)
1ae68c91 hotfix(models): disable temperature and top_p for Kimi K2.6
(#14580)
63be624f fix(models): add vision and reasoning_effort support for
mistral-small-2603 (#14541)
4e1e4548 hotfix(deepseek): forward reasoning effort for DeepSeek V4+ via
Claude endpoint (#14572)
5a1b20fe hotfix(models): add MiMo V2.5 model support (#14557)
774aa674 hotfix(copilot): github copilot model fetch (#14566)
e17d5737 hotfix(models): add DeepSeek V4+ model support with reasoning
effort (#14551)
19f2ed67 fix: remove push trigger for versioned tags in release workflow

### Review Checklist

- [ ] Review generated release notes in `electron-builder.yml`
- [ ] Verify version bump in `package.json` (1.9.3 → 1.9.4)
- [ ] CI passes
- [ ] Merge to trigger release build

### Breaking Changes

None. The removal of auto-injected @cherry/browser MCP requires users
who depended on it to manually re-enable a browsing MCP.

### 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 code before requesting review from
others

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-28 13:02:35 +08:00
SuYao
4e1e4548bb hotfix(deepseek): forward reasoning effort for DeepSeek V4+ via Claude endpoint (#14572)
### What this PR does

Before this PR:

- For DeepSeek V4+ models served through a Claude-compatible endpoint,
`getAnthropicReasoningParams` returned only `{ thinking: { type:
'enabled', budgetTokens } }`. The requested `reasoning_effort` was
dropped before the request left the client, so `high` / `xhigh` behaved
identically to default.
- `@ai-sdk/deepseek` had no `reasoning_effort` field on its Zod options
schema, so even if the effort were forwarded the SDK would strip it from
the request body.
- `@ai-sdk/anthropic` silently omitted the `thinking` field when
thinking was turned off, preventing downstream providers that require an
explicit `{ type: 'disabled' }` from honoring the disable.

After this PR:

- Non-Anthropic Claude-endpoint models (Kimi, MiniMax, DeepSeek V4+,
etc.) receive `sendReasoning: true` so reasoning output is actually
streamed back.
- DeepSeek V4+ additionally receives `effort: 'max'` when the user picks
`xhigh`, otherwise `effort: 'high'`.
- `@ai-sdk/deepseek@2.0.29` is patched to accept `reasoning_effort` on
its language-model options schema and forward it into the request body.
- `@ai-sdk/anthropic` is patched to emit an explicit `thinking: { type:
'disabled' }` when thinking is disabled.
- Updated one existing `getAnthropicReasoningParams` unit test to assert
the new `sendReasoning: true` payload, and added a new V4+ reasoning
test suite.

Fixes #

### Why we need it and why it was done in this way

Follow-up to #14551, which introduced `isDeepSeekV4PlusModel` and the
`deepseek_v4` reasoning category but did not wire the selected effort
into the outgoing request for the Claude-compatible endpoint path.
Without this PR the `high` / `xhigh` options are cosmetic for V4+.

The following tradeoffs were made:

- Patched upstream SDKs (`@ai-sdk/deepseek`, `@ai-sdk/anthropic`)
instead of waiting for upstream releases, so the fix ships on `main`'s
code freeze window. Patches are narrow (single field additions).
- Kept all non-Anthropic Claude-endpoint models on `sendReasoning: true`
rather than gating per-provider — the field is harmless for providers
that don't emit reasoning and restores visibility for those that do.

The following alternatives were considered:

- Upstreaming the `reasoning_effort` change to `@ai-sdk/deepseek` —
rejected for timing; patch is mechanical and easy to drop once upstream
lands.
- Sending effort via a custom header — rejected; DeepSeek documents
`reasoning_effort` in the request body.

Links to places where the discussion took place:

### Breaking changes

None. The added fields (`sendReasoning`, `effort`, `reasoning_effort`)
are additive and only take effect for models already routed through the
Claude-compatible path with reasoning enabled.

### Special notes for your reviewer

- Two new patch files under `patches/` are registered in
`package.json#pnpm.patchedDependencies`; they are narrow dist-only
additions.
- The implementation change is localized to
`getAnthropicReasoningParams` in
`src/renderer/src/aiCore/utils/reasoning.ts`.
- Targeting `main` via `hotfix/*` branch per the branch-strategy rule,
since this restores intended V4+ behavior shipped in #14551 and contains
no refactoring.

### 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
Fix: DeepSeek V4+ reasoning effort (high / xhigh) is now actually forwarded to the API when the model is served via a Claude-compatible endpoint; reasoning output is also streamed back to the UI.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 02:12:47 +08:00
亢奋猫
e72b77a09b chore: release v1.9.3 (#14523)
### What this PR does

This PR prepares the release of Cherry Studio v1.9.3.

**Release Summary:**

Cherry Studio 1.9.3 is a bug fix release that addresses 17 issues across
various components:

- [Web Search] Fix built-in web search repeatedly running and consuming
excessive tokens
- [Backup] Fix Windows backup failures caused by symlinks in the Data
directory
- [UI] Fix horizontal multi-model message scrolling issue on card edges
- [Models] Add support for OpenAI's gpt-image-2 model
- [MCP] Fix MCP SSE/streamableHttp servers timing out during
initialization
- [AI Core] Fix native tool-call conversations stopping after first
execution
- [Bedrock] Fix AWS Bedrock requests failing when API Host is blank
- [Agents] Fix agent skills page scroll position reset when toggling
skills
- [Feishu] Restore image message support from Feishu/Lark bot users
- [Proxy Providers] Fix structured output error with Claude models
through AiHubMix/NewAPI
- [API Server] Fix API server failing for providers with comma-separated
API keys
- [Agents] Fix Soul Mode dropping user-provided session instructions
- [File Upload] Support case-insensitive file extensions for
drag-and-drop uploads
- [Deep Links] Fix "Open in VS Code/Cursor/Zed" buttons being blocked
- [Proxy Providers] Fix custom parameters not being passed for
CherryIN/NewAPI
- [Claude Code] Fix Claude Code failing to launch on all platforms
- [Quick Panel] Fix model deselection bug when pasting messages with "@"

**Changes in this release:**

1. Updated version to 1.9.3 in `package.json`
2. Updated release notes in `electron-builder.yml`

### Included Commits

- 0636b601f fix: limit builtin web search usage (#14466)
- 930fdf75b fix: handle symlinks during backup copy (#14471)
- 09da6a336 fix: prevent outer scrolling in horizontal multi-model
messages (#13964)
- c0b3c880e hotfix(ai-sdk/openai): patch @ai-sdk/openai to support
gpt-image-2 (#14488)
- 5cc1b9c41 fix(mcp): delegate connect timeout to SDK to restore slow
SSE servers (#14348)
- 5d98273d8 fix(ai-core): keep native tool loops going (#14481)
- c4b3a93ab fix: prevent empty baseURL/region string in Bedrock provider
config (#14425)
- 47fb14c65 fix(useInstalledSkills): keep agent skills list stable while
toggling (#14472)
- fbf73962c fix(feishu): handle image messages from IM channel (#14421)
- 01caaf06f hotfix: disable native structured output for AiHubMix/NewAPI
Anthropic models (#14376)
- 3f463e178 fix(api-server): rotate comma-separated provider API keys
(#14346)
- ec4e787d1 fix(agents): preserve session instructions in Soul Mode
(#14424)
- ccb047c3c hotfix: Support case-insensitive file extensions for
drag-and-drop (#14416)
- 84240baa4 fix(security): allow vscode/cursor/zed deep-links in
openExternal (#14437)
- c2b330258 hotfix: Custom params dropped by CherryIN/NewAPI — respect
model.endpoint_type (#14409)
- 4c0ce8f79 fix: use cli-wrapper.cjs to launch claude-code instead of
native binary (#14430)
- cd6d84c84 fix(quick-panel): reset stale state on panel close to
prevent model deselection (#14378)

### Review Checklist

- [ ] Review generated release notes in `electron-builder.yml`
- [ ] Verify version bump in `package.json`
- [ ] CI passes
- [ ] Merge to trigger release build

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

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 11:13:49 +08:00
fullex
5ec8696fd2 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-23 19:13:26 -07:00
SuYao
c0b3c880e3 hotfix(ai-sdk/openai): patch @ai-sdk/openai to support gpt-image-2 (#14488)
### What this PR does

Before this PR:

Calling the newly-released `gpt-image-2` model (shipped 2026-04-21) via
OpenAI image generation fails with `400 Unknown parameter:
'response_format'`. `@ai-sdk/openai@3.0.49` (our current AI SDK v6 line
dep) unconditionally sends `response_format: 'b64_json'` for any model
not in its `defaultResponseFormatPrefixes` allow-list, and `gpt-image-2`
is not in that list.

After this PR:

`@ai-sdk/openai@3.0.49` is patched to add `gpt-image-2` to both
`modelMaxImagesPerCall` and `defaultResponseFormatPrefixes` in all four
compiled dist entry points (`dist/index.{js,mjs}`,
`dist/internal/index.{js,mjs}`). This mirrors vercel/ai#14680, which was
backported to `release-v6.0` via vercel/ai#14682 on 2026-04-21 but has
not yet been published to npm. The patch is registered in
`pnpm.patchedDependencies` alongside the existing AI SDK patches.

Fixes #14485

### Why we need it and why it was done in this way

The upstream fix (vercel/ai#14680 / #14682) is already merged into the
`release-v6.0` branch, so a patch is a stable, low-risk equivalent of
the forthcoming `@ai-sdk/openai@3.0.54+`. Once that version ships on
npm, this patch can be dropped and replaced with a dependency bump.

The following tradeoffs were made:

- Patching compiled `dist/` files instead of source: matches the
repository's existing convention (see
`patches/@ai-sdk__google@3.0.55.patch`,
`patches/@ai-sdk__openai-compatible@2.0.37.patch`) and avoids rebuilding
the package.
- Not touching `.d.ts` type declarations: the upstream
`OpenAIImageModelId` union already accepts `(string & {})`, so runtime
behavior is the only thing that needs correcting.

The following alternatives were considered:

- Waiting for the npm release of `@ai-sdk/openai@3.0.54` — rejected
because users are actively hitting the bug today.
- Using a pnpm `overrides` entry pointing at the `release-v6.0` git
branch — rejected because it pulls an unversioned moving target and
conflicts with the locked semver range.
- Stripping `response_format` in an `aiCore` plugin — rejected because
the fix belongs at the provider layer and a plugin would permanently
mask similar issues for other models.

Links to places where the discussion took place: vercel/ai#14680,
vercel/ai#14682

### Breaking changes

None.

### Special notes for your reviewer

- The patch adds `gpt-image-2` at the expected positions in each of the
four dist files; diff is small and mechanical. Verified locally:
`node_modules/@ai-sdk/openai/dist/index.js:1753,1761` now contain
`gpt-image-2` after `pnpm install`.
- UI model picker changes are intentionally out of scope. Users select
`gpt-image-2` by model ID today; once upstream publishes, a follow-up
can refresh `src/renderer/src/config/models/default.ts` and friends.

### 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
fix(ai-sdk/openai): patch @ai-sdk/openai to support OpenAI's gpt-image-2 model, resolving "Unknown parameter: 'response_format'" errors.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-22 23:29:50 +08:00
fullex
b414dc52dc refactor(data-providers): migrate to handwritten Zod schema and remove drizzle-zod
- Replace userProviderInsertSchema (drizzle-zod generated) with a
  handwritten ProviderSchema + CreateProviderSchema / UpdateProviderSchema
  in api/schemas/providers.ts
- Update providers handler to .parse() through the new schemas
- Strip drizzle-zod generator blocks from userProvider.ts and the dead
  userModelInsertSchema / userModelSelectSchema from userModel.ts
- Drop drizzle-zod dependency; drizzle-zod is being deprecated in
  drizzle v1 and its .pick()/.omit() TS output conflicts with the
  new whitelist derivation convention
2026-04-22 05:14:56 -07:00
fullex
572202ae54 feat(data-ordering): order-key infrastructure for sortable resources 2026-04-21 03:21:05 -07:00
LiuVaayne
9f3be4bc19 feat: migrate agents storage to v2 main database (#14159)
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
2026-04-20 21:43:49 +08:00
fullex
9f4026f5ec Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-20 01:39:00 -07:00
亢奋猫
c88f6aa787 refactor: stabilize ui package boundaries and theme contracts (#14328)
Co-authored-by: MyPrototypeWhat <daoquqiexing@gmail.com>
Fixes #14331
2026-04-20 16:12:02 +08:00
亢奋猫
260c5458f2 chore: release v1.9.2 (#14406)
### What this PR does

Before this PR:
- Version 1.9.1 was the latest release
- Several user-facing bugs and feature requests needed to be addressed

After this PR:
- Bumps version to 1.9.2
- Updates release notes with bilingual (English/Chinese) changelog

### Summary of Changes

This release includes 20 commits since v1.9.1, featuring:

**New Features:**
- Vietnamese language support (Tiếng Việt)
- Agents can now author and register new skills directly from chat
- Skills/memory tools now available to all agents

**Bug Fixes:**
- Agent settings now sync immediately to active sessions
- Fixed telemetry being sent despite data collection disabled
- Fixed CJK text search failures and added phrase search
- Fixed Obsidian export silently failing
- Fixed Ollama model loading and knowledge base issues
- Fixed custom parameters not passing to Gemini API via NewAPI/AiHubMix
- Various other fixes for Dify, Cherry Assistant, and OpenClaw

**Included Commits:**
- 2120fddf4 fix: update node-abi for Electron 41 packaging
- 7c2ada6d6 fix(analytics): respect data collection setting for all
tracking events
- da2302237 fix: Fix Ollama model list loading when metadata contains
null families values
- 76ec2f1c0 fix(export): add obsidian:// to allowed protocol whitelist
- d89ce0871 fix(search): support phrase search and fix CJK matching in
history search
- fbda0d213 hotfix: Custom params not passed to Gemini API when using
NewAPI/AiHubMix
- 7afabbdf2 fix(agents): set Cherry Assistant default avatar to 🍒
- b85c28d50 fix(knowledge): support Ollama knowledge embeddings
- 41554411d fix: sync builtin agent prompt updates to sessions
- 6b5cb0b76 feat(i18n): add Vietnamese (vi-VN) language support
- bf3235be8 fix(selection): upgrade electron to 41.2.1
- 0477bd0ad fix(skills): per-agent skill enablement with workspace
symlinks
- 68d32c7f7 fix: limit topic naming retries and timeout
- ae8f0888b fix(agents): add more skills button to agent skills settings
missing
- e2366b351 fix: update dify knowledge retrieval payload
- 0d7e13bd4 fix(skills): support agent-authored skills via skills tool
init/register
- 51eed6e74 fix(agents): sync agent settings changes to active session
- e54cfe97e fix(agents): set NODE_PATH so spawned Claude Code process
can resolve @img/sharp
- d75883d63 fix(openclaw): persist language selection in overview page

### Review Checklist

- [ ] Review generated release notes in `electron-builder.yml`
- [ ] Verify version bump in `package.json` (1.9.1 → 1.9.2)
- [ ] CI passes
- [ ] Merge to trigger release build

### Release note

See the bilingual release notes in `electron-builder.yml` for full
details.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-20 13:55:26 +08:00
亢奋猫
2120fddf4e fix: update node-abi for Electron 41 packaging (#14403)
### What this PR does

Before this PR:
Packaging failed after upgrading to Electron 41.2.1 because the pinned
`node-abi` version could not resolve the ABI for the new Electron
runtime.

After this PR:
Packaging uses `node-abi` 4.28.0, which recognizes Electron 41.2.1 and
allows the build pipeline to resolve the correct ABI during packaging.

<!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)`
format, will close the issue(s) when PR gets merged)*: -->

Fixes #N/A

### Why we need it and why it was done in this way

The following tradeoffs were made:
A minimal override-only change was used so the fix stays suitable for a
`hotfix/*` branch and avoids unrelated packaging or dependency
refactors.

The following alternatives were considered:
Upgrading broader packaging dependencies such as `electron-builder` and
related transitive tooling was considered, but rejected because it would
increase scope and risk for a hotfix.

Links to places where the discussion took place: <!-- optional: slack,
other GH issue, mailinglist, ... -->
N/A

### Breaking changes

<!-- optional -->

If this PR introduces breaking changes, please describe the changes and
the impact on users.

N/A

### Special notes for your reviewer

This PR only updates the pinned `node-abi` override and lockfile entries
required for Electron 41.2.1 packaging.

Validation performed locally:
- `pnpm format`
- `pnpm test`
- `pnpm lint`

### 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
- [ ] 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
NONE
```

Signed-off-by: kangfenmao <kangfenmao@qq.com>
2026-04-20 12:23:49 +08:00
404-Page-Found
b85c28d50c fix(knowledge): support Ollama knowledge embeddings (#14172)
### What this PR does

Before this PR:
- Creating a knowledge base with an Ollama embedding model such as
`nomic-embed-text` could fail during initialization with `Cannot read
properties of undefined (reading '0')`.

After this PR:
- Knowledge base initialization keeps using
`@cherrystudio/embedjs-ollama` instead of a Cherry Studio-only Ollama
adapter.
- The PR applies the Ollama response-handling hotfix in a scoped `pnpm`
patch for `@cherrystudio/embedjs-ollama`.
- The patched library handles the current `/api/embed` response shape
and falls back to the legacy `/api/embeddings` response during dimension
detection.
- A focused regression test covers configured dimensions, current Ollama
responses, and legacy fallback behavior.

Fixes #14168

### Why we need it and why it was done in this way

The following tradeoffs were made:
- Moved the fix from app-local code into a patched
`@cherrystudio/embedjs-ollama` dependency so Cherry Studio can keep
using the library abstraction on the frozen `main` branch.
- Kept support for both current and legacy Ollama embedding APIs because
the failure happens during dimension probing before any documents are
added.

The following alternatives were considered:
- Keeping the Cherry Studio-only `OllamaEmbeddings` adapter introduced
in the first revision of this PR.
- Opening an upstream `CherryHQ/embed-js` PR first and waiting for a
released package version before fixing Cherry Studio.
- Patching `@langchain/ollama` or widening shared dependency changes on
`main`.

Links to places where the discussion took place:
https://github.com/CherryHQ/cherry-studio/pull/14172#issuecomment-4229167072

### Breaking changes

If this PR introduces breaking changes, please describe the changes and
the impact on users.

None.

### Special notes for your reviewer

- Per review, this PR no longer keeps a Cherry Studio-only Ollama
adapter; the fix now lives in the patched `@cherrystudio/embedjs-ollama`
dependency.
- `pnpm exec vitest run
src/main/knowledge/embedjs/embeddings/__tests__/OllamaEmbeddings.test.ts`
passed.
- `pnpm lint` completed successfully.
- `pnpm test` still fails in pre-existing CherryClaw prompt tests under
`src/main/services/agents/services/cherryclaw/__tests__/prompt.test.ts`;
these failures are unrelated to this hotfix.

### 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

```release-note
Fix knowledge base creation for Ollama embedding models such as `nomic-embed-text` by handling current and legacy Ollama embedding API responses through `@cherrystudio/embedjs-ollama` during dimension detection.
```

---------

Signed-off-by: 404-Page-Found <Lucas20220605@gmail.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
2026-04-17 18:33:07 +08:00
dependabot[bot]
d1652da1ff chore(deps): bump form-data from 2.3.3 to 4.0.4 (#14295)
Bumps [form-data](https://github.com/form-data/form-data) from 2.3.3 to
4.0.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/form-data/form-data/releases">form-data's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.4</h2>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4">v4.0.4</a>
- 2025-07-16</h2>
<h3>Commits</h3>
<ul>
<li>[meta] add <code>auto-changelog</code> <a
href="811f68282f"><code>811f682</code></a></li>
<li>[Tests] handle predict-v8-randomness failures in node &lt; 17 and
node &gt; 23 <a
href="1d11a76434"><code>1d11a76</code></a></li>
<li>[Fix] Switch to using <code>crypto</code> random for boundary values
<a
href="3d1723080e"><code>3d17230</code></a></li>
<li>[Tests] fix linting errors <a
href="5e340800b5"><code>5e34080</code></a></li>
<li>[meta] actually ensure the readme backup isn’t published <a
href="316c82ba93"><code>316c82b</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code> <a
href="58c25d7640"><code>58c25d7</code></a></li>
<li>[meta] fix readme capitalization <a
href="2300ca1959"><code>2300ca1</code></a></li>
</ul>
<h2>v4.0.3</h2>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.2...v4.0.3">v4.0.3</a>
- 2025-06-05</h2>
<h3>Fixed</h3>
<ul>
<li>[Fix] <code>append</code>: avoid a crash on nullish values <a
href="https://redirect.github.com/form-data/form-data/issues/577"><code>[#577](https://github.com/form-data/form-data/issues/577)</code></a></li>
</ul>
<h3>Commits</h3>
<ul>
<li>[eslint] use a shared config <a
href="426ba9ac44"><code>426ba9a</code></a></li>
<li>[eslint] fix some spacing issues <a
href="20941917f0"><code>2094191</code></a></li>
<li>[Refactor] use <code>hasown</code> <a
href="81ab41b46f"><code>81ab41b</code></a></li>
<li>[Fix] validate boundary type in <code>setBoundary()</code> method <a
href="8d8e469309"><code>8d8e469</code></a></li>
<li>[Tests] add tests to check the behavior of <code>getBoundary</code>
with non-strings <a
href="837b8a1f75"><code>837b8a1</code></a></li>
<li>[Dev Deps] remove unused deps <a
href="870e4e6659"><code>870e4e6</code></a></li>
<li>[meta] remove local commit hooks <a
href="e6e83ccb54"><code>e6e83cc</code></a></li>
<li>[Dev Deps] update <code>eslint</code> <a
href="4066fd6f65"><code>4066fd6</code></a></li>
<li>[meta] fix scripts to use prepublishOnly <a
href="c4bbb13c0e"><code>c4bbb13</code></a></li>
</ul>
<h2>v4.0.2</h2>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.1...v4.0.2">v4.0.2</a>
- 2025-02-14</h2>
<h3>Merged</h3>
<ul>
<li>[Fix] set <code>Symbol.toStringTag</code> when available <a
href="https://redirect.github.com/form-data/form-data/pull/573"><code>[#573](https://github.com/form-data/form-data/issues/573)</code></a></li>
<li>[Fix] set <code>Symbol.toStringTag</code> when available <a
href="https://redirect.github.com/form-data/form-data/pull/573"><code>[#573](https://github.com/form-data/form-data/issues/573)</code></a></li>
<li>fix (npmignore): ignore temporary build files <a
href="https://redirect.github.com/form-data/form-data/pull/532"><code>[#532](https://github.com/form-data/form-data/issues/532)</code></a></li>
<li>fix (npmignore): ignore temporary build files <a
href="https://redirect.github.com/form-data/form-data/pull/532"><code>[#532](https://github.com/form-data/form-data/issues/532)</code></a></li>
</ul>
<h3>Fixed</h3>
<ul>
<li>[Fix] set <code>Symbol.toStringTag</code> when available (<a
href="https://redirect.github.com/form-data/form-data/issues/573">#573</a>)
<a
href="https://redirect.github.com/form-data/form-data/issues/396"><code>[#396](https://github.com/form-data/form-data/issues/396)</code></a></li>
<li>[Fix] set <code>Symbol.toStringTag</code> when available (<a
href="https://redirect.github.com/form-data/form-data/issues/573">#573</a>)
<a
href="https://redirect.github.com/form-data/form-data/issues/396"><code>[#396](https://github.com/form-data/form-data/issues/396)</code></a></li>
<li>[Fix] set <code>Symbol.toStringTag</code> when available <a
href="https://redirect.github.com/form-data/form-data/issues/396"><code>[#396](https://github.com/form-data/form-data/issues/396)</code></a></li>
</ul>
<h3>Commits</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/form-data/form-data/blob/master/CHANGELOG.md">form-data's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4">v4.0.4</a>
- 2025-07-16</h2>
<h3>Commits</h3>
<ul>
<li>[meta] add <code>auto-changelog</code> <a
href="811f68282f"><code>811f682</code></a></li>
<li>[Tests] handle predict-v8-randomness failures in node &lt; 17 and
node &gt; 23 <a
href="1d11a76434"><code>1d11a76</code></a></li>
<li>[Fix] Switch to using <code>crypto</code> random for boundary values
<a
href="3d1723080e"><code>3d17230</code></a></li>
<li>[Tests] fix linting errors <a
href="5e340800b5"><code>5e34080</code></a></li>
<li>[meta] actually ensure the readme backup isn’t published <a
href="316c82ba93"><code>316c82b</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code> <a
href="58c25d7640"><code>58c25d7</code></a></li>
<li>[meta] fix readme capitalization <a
href="2300ca1959"><code>2300ca1</code></a></li>
</ul>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.2...v4.0.3">v4.0.3</a>
- 2025-06-05</h2>
<h3>Fixed</h3>
<ul>
<li>[Fix] <code>append</code>: avoid a crash on nullish values <a
href="https://redirect.github.com/form-data/form-data/issues/577"><code>[#577](https://github.com/form-data/form-data/issues/577)</code></a></li>
</ul>
<h3>Commits</h3>
<ul>
<li>[eslint] use a shared config <a
href="426ba9ac44"><code>426ba9a</code></a></li>
<li>[eslint] fix some spacing issues <a
href="20941917f0"><code>2094191</code></a></li>
<li>[Refactor] use <code>hasown</code> <a
href="81ab41b46f"><code>81ab41b</code></a></li>
<li>[Fix] validate boundary type in <code>setBoundary()</code> method <a
href="8d8e469309"><code>8d8e469</code></a></li>
<li>[Tests] add tests to check the behavior of <code>getBoundary</code>
with non-strings <a
href="837b8a1f75"><code>837b8a1</code></a></li>
<li>[Dev Deps] remove unused deps <a
href="870e4e6659"><code>870e4e6</code></a></li>
<li>[meta] remove local commit hooks <a
href="e6e83ccb54"><code>e6e83cc</code></a></li>
<li>[Dev Deps] update <code>eslint</code> <a
href="4066fd6f65"><code>4066fd6</code></a></li>
<li>[meta] fix scripts to use prepublishOnly <a
href="c4bbb13c0e"><code>c4bbb13</code></a></li>
</ul>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.1...v4.0.2">v4.0.2</a>
- 2025-02-14</h2>
<h3>Merged</h3>
<ul>
<li>[Fix] set <code>Symbol.toStringTag</code> when available <a
href="https://redirect.github.com/form-data/form-data/pull/573"><code>[#573](https://github.com/form-data/form-data/issues/573)</code></a></li>
<li>[Fix] set <code>Symbol.toStringTag</code> when available <a
href="https://redirect.github.com/form-data/form-data/pull/573"><code>[#573](https://github.com/form-data/form-data/issues/573)</code></a></li>
<li>fix (npmignore): ignore temporary build files <a
href="https://redirect.github.com/form-data/form-data/pull/532"><code>[#532](https://github.com/form-data/form-data/issues/532)</code></a></li>
<li>fix (npmignore): ignore temporary build files <a
href="https://redirect.github.com/form-data/form-data/pull/532"><code>[#532](https://github.com/form-data/form-data/issues/532)</code></a></li>
</ul>
<h3>Fixed</h3>
<ul>
<li>[Fix] set <code>Symbol.toStringTag</code> when available (<a
href="https://redirect.github.com/form-data/form-data/issues/573">#573</a>)
<a
href="https://redirect.github.com/form-data/form-data/issues/396"><code>[#396](https://github.com/form-data/form-data/issues/396)</code></a></li>
<li>[Fix] set <code>Symbol.toStringTag</code> when available (<a
href="https://redirect.github.com/form-data/form-data/issues/573">#573</a>)
<a
href="https://redirect.github.com/form-data/form-data/issues/396"><code>[#396](https://github.com/form-data/form-data/issues/396)</code></a></li>
<li>[Fix] set <code>Symbol.toStringTag</code> when available <a
href="https://redirect.github.com/form-data/form-data/issues/396"><code>[#396](https://github.com/form-data/form-data/issues/396)</code></a></li>
</ul>
<h3>Commits</h3>
<ul>
<li>Merge tags v2.5.3 and v3.0.3 <a
href="92613b9208"><code>92613b9</code></a></li>
<li>[Tests] migrate from travis to GHA <a
href="806eda7774"><code>806eda7</code></a></li>
<li>[Tests] migrate from travis to GHA <a
href="8fdb3bc6b5"><code>8fdb3bc</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/form-data/form-data/commits/v4.0.4">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~ljharb">ljharb</a>, a new releaser for
form-data since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version modifies <code>prepublish</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=form-data&package-manager=npm_and_yarn&previous-version=2.3.3&new-version=4.0.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/CherryHQ/cherry-studio/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-16 23:33:30 +08:00
dependabot[bot]
365377bd03 chore(deps-dev): bump lodash from 4.17.21 to 4.18.1 (#14294)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.18.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lodash/lodash/releases">lodash's
releases</a>.</em></p>
<blockquote>
<h2>4.18.1</h2>
<h2>Bugs</h2>
<p>Fixes a <code>ReferenceError</code> issue in <code>lodash</code>
<code>lodash-es</code> <code>lodash-amd</code> and
<code>lodash.template</code> when using the <code>template</code> and
<code>fromPairs</code> functions from the modular builds. See <a
href="https://redirect.github.com/lodash/lodash/issues/6167#issuecomment-4165269769">lodash/lodash#6167</a></p>
<p>These defects were related to how lodash distributions are built from
the main branch using <a
href="https://github.com/lodash-archive/lodash-cli">https://github.com/lodash-archive/lodash-cli</a>.
When internal dependencies change inside lodash functions, equivalent
updates need to be made to a mapping in the lodash-cli. (hey, it was
ahead of its time once upon a time!). We know this, but we missed it in
the last release. It's the kind of thing that passes in CI, but fails bc
the build is not the same thing you tested.</p>
<p>There is no diff on main for this, but you can see the diffs for each
of the npm packages on their respective branches:</p>
<ul>
<li><code>lodash</code>: <a
href="https://github.com/lodash/lodash/compare/4.18.0-npm...4.18.1-npm">https://github.com/lodash/lodash/compare/4.18.0-npm...4.18.1-npm</a></li>
<li><code>lodash-es</code>: <a
href="https://github.com/lodash/lodash/compare/4.18.0-es...4.18.1-es">https://github.com/lodash/lodash/compare/4.18.0-es...4.18.1-es</a></li>
<li><code>lodash-amd</code>: <a
href="https://github.com/lodash/lodash/compare/4.18.0-amd...4.18.1-amd">https://github.com/lodash/lodash/compare/4.18.0-amd...4.18.1-amd</a></li>
<li><code>lodash.template</code><a
href="https://github.com/lodash/lodash/compare/4.18.0-npm-packages...4.18.1-npm-packages">https://github.com/lodash/lodash/compare/4.18.0-npm-packages...4.18.1-npm-packages</a></li>
</ul>
<h2>4.18.0</h2>
<h2>v4.18.0</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lodash/lodash/compare/4.17.23...4.18.0">https://github.com/lodash/lodash/compare/4.17.23...4.18.0</a></p>
<h3>Security</h3>
<p><strong><code>_.unset</code> / <code>_.omit</code></strong>: Fixed
prototype pollution via <code>constructor</code>/<code>prototype</code>
path traversal (<a
href="https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh">GHSA-f23m-r3pf-42rh</a>,
<a
href="fe8d32eda8">fe8d32e</a>).
Previously, array-wrapped path segments and primitive roots could bypass
the existing guards, allowing deletion of properties from built-in
prototypes. Now <code>constructor</code> and <code>prototype</code> are
blocked unconditionally as non-terminal path keys, matching
<code>baseSet</code>. Calls that previously returned <code>true</code>
and deleted the property now return <code>false</code> and leave the
target untouched.</p>
<p><strong><code>_.template</code></strong>: Fixed code injection via
<code>imports</code> keys (<a
href="https://github.com/lodash/lodash/security/advisories/GHSA-r5fr-rjxr-66jc">GHSA-r5fr-rjxr-66jc</a>,
CVE-2026-4800, <a
href="879aaa9313">879aaa9</a>).
Fixes an incomplete patch for CVE-2021-23337. The <code>variable</code>
option was validated against <code>reForbiddenIdentifierChars</code> but
<code>importsKeys</code> was left unguarded, allowing code injection via
the same <code>Function()</code> constructor sink. <code>imports</code>
keys containing forbidden identifier characters now throw
<code>&quot;Invalid imports option passed into
_.template&quot;</code>.</p>
<h3>Docs</h3>
<ul>
<li>Add security notice for <code>_.template</code> in threat model and
API docs (<a
href="https://redirect.github.com/lodash/lodash/pull/6099">#6099</a>)</li>
<li>Document <code>lower &gt; upper</code> behavior in
<code>_.random</code> (<a
href="https://redirect.github.com/lodash/lodash/pull/6115">#6115</a>)</li>
<li>Fix quotes in <code>_.compact</code> jsdoc (<a
href="https://redirect.github.com/lodash/lodash/pull/6090">#6090</a>)</li>
</ul>
<h3><code>lodash.*</code> modular packages</h3>
<p><a
href="https://redirect.github.com/lodash/lodash/pull/6157">Diff</a></p>
<p>We have also regenerated and published a select number of the
<code>lodash.*</code> modular packages.</p>
<p>These modular packages had fallen out of sync significantly from the
minor/patch updates to lodash. Specifically, we have brought the
following packages up to parity w/ the latest lodash release because
they have had CVEs on them in the past:</p>
<ul>
<li><a
href="https://www.npmjs.com/package/lodash.orderby">lodash.orderby</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.tonumber">lodash.tonumber</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.trim">lodash.trim</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.trimend">lodash.trimend</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.sortedindexby">lodash.sortedindexby</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.zipobjectdeep">lodash.zipobjectdeep</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.unset">lodash.unset</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.omit">lodash.omit</a></li>
<li><a
href="https://www.npmjs.com/package/lodash.template">lodash.template</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="cb0b9b9212"><code>cb0b9b9</code></a>
release(patch): bump main to 4.18.1 (<a
href="https://redirect.github.com/lodash/lodash/issues/6177">#6177</a>)</li>
<li><a
href="75535f5788"><code>75535f5</code></a>
chore: prune stale advisory refs (<a
href="https://redirect.github.com/lodash/lodash/issues/6170">#6170</a>)</li>
<li><a
href="62e91bc6a3"><code>62e91bc</code></a>
docs: remove n_ Node.js &lt; 6 REPL note from README (<a
href="https://redirect.github.com/lodash/lodash/issues/6165">#6165</a>)</li>
<li><a
href="59be2de61f"><code>59be2de</code></a>
release(minor): bump to 4.18.0 (<a
href="https://redirect.github.com/lodash/lodash/issues/6161">#6161</a>)</li>
<li><a
href="af63457303"><code>af63457</code></a>
fix: broken tests for _.template 879aaa9</li>
<li><a
href="1073a7693e"><code>1073a76</code></a>
fix: linting issues</li>
<li><a
href="879aaa9313"><code>879aaa9</code></a>
fix: validate imports keys in _.template</li>
<li><a
href="fe8d32eda8"><code>fe8d32e</code></a>
fix: block prototype pollution in baseUnset via constructor/prototype
traversal</li>
<li><a
href="18ba0a32f4"><code>18ba0a3</code></a>
refactor(fromPairs): use baseAssignValue for consistent assignment (<a
href="https://redirect.github.com/lodash/lodash/issues/6153">#6153</a>)</li>
<li><a
href="b8190803d4"><code>b819080</code></a>
ci: add dist sync validation workflow (<a
href="https://redirect.github.com/lodash/lodash/issues/6137">#6137</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/lodash/lodash/compare/4.17.21...4.18.1">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-16 14:39:44 +08:00
dependabot[bot]
3499c2ed9d chore(deps-dev): bump axios from 1.13.2 to 1.15.0 (#14293)
Bumps [axios](https://github.com/axios/axios) from 1.13.2 to 1.15.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>v1.15.0</h2>
<p>This release delivers two critical security patches, adds runtime
support for Deno and Bun, and includes significant CI hardening,
documentation improvements, and routine dependency updates.</p>
<h2>⚠️ Important Changes</h2>
<ul>
<li><strong>Deprecation:</strong> <code>url.parse()</code> usage has
been replaced to address Node.js deprecation warnings. If you are on a
recent version of Node.js, this resolves console warnings you may have
been seeing. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li>
</ul>
<h2>🔒 Security Fixes</h2>
<ul>
<li><strong>Proxy Handling:</strong> Fixed a <code>no_proxy</code>
hostname normalisation bypass that could lead to Server-Side Request
Forgery (SSRF). (<strong><a
href="https://redirect.github.com/axios/axios/issues/10661">#10661</a></strong>)</li>
<li><strong>Header Injection:</strong> Fixed an unrestricted cloud
metadata exfiltration vulnerability via a header injection chain.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10660">#10660</a></strong>)</li>
</ul>
<h2>🚀 New Features</h2>
<ul>
<li><strong>Runtime Support:</strong> Added compatibility checks and
documentation for Deno and Bun environments. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10652">#10652</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10653">#10653</a></strong>)</li>
</ul>
<h2>🔧 Maintenance &amp; Chores</h2>
<ul>
<li><strong>CI Security:</strong> Hardened workflow permissions to least
privilege, added the <code>zizmor</code> security scanner, pinned action
versions, and gated npm publishing with OIDC and environment protection.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10618">#10618</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10619">#10619</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10627">#10627</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10637">#10637</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10666">#10666</a></strong>)</li>
<li><strong>Dependencies:</strong> Bumped
<code>serialize-javascript</code>, <code>handlebars</code>,
<code>picomatch</code>, <code>vite</code>, and
<code>denoland/setup-deno</code> to latest versions. Added a 7-day
Dependabot cooldown period. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10574">#10574</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10572">#10572</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10568">#10568</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10663">#10663</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10664">#10664</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10665">#10665</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10669">#10669</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10670">#10670</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10616">#10616</a></strong>)</li>
<li><strong>Documentation:</strong> Unified docs, improved
<code>beforeRedirect</code> credential leakage example, clarified
<code>withCredentials</code>/<code>withXSRFToken</code> behaviour,
HTTP/2 support notes, async/await timeout error handling, header case
preservation, and various typo fixes. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10649">#10649</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/7452">#7452</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/7471">#7471</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10654">#10654</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10644">#10644</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10589">#10589</a></strong>)</li>
<li><strong>Housekeeping:</strong> Removed stale files, regenerated
lockfile, and updated sponsor scripts and blocks. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10584">#10584</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10650">#10650</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10582">#10582</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10640">#10640</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10659">#10659</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10668">#10668</a></strong>)</li>
<li><strong>Tests:</strong> Added regression coverage for urlencoded
<code>Content-Type</code> casing. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10573">#10573</a></strong>)</li>
</ul>
<h2>🌟 New Contributors</h2>
<p>We are thrilled to welcome our new contributors. Thank you for
helping improve Axios:</p>
<ul>
<li><strong><a
href="https://github.com/raashish1601"><code>@​raashish1601</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10573">#10573</a></strong>)</li>
<li><strong><a
href="https://github.com/Kilros0817"><code>@​Kilros0817</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li>
<li><strong><a
href="https://github.com/ashstrc"><code>@​ashstrc</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>)</li>
<li><strong><a
href="https://github.com/Abhi3975"><code>@​Abhi3975</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10589">#10589</a></strong>)</li>
<li><strong><a
href="https://github.com/theamodhshetty"><code>@​theamodhshetty</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/7452">#7452</a></strong>)</li>
</ul>
<h2>v1.14.0</h2>
<p>This release focuses on compatibility fixes, adapter stability
improvements, and test/tooling modernisation.</p>
<h2>⚠️ Important Changes</h2>
<ul>
<li><strong>Breaking Changes:</strong> None identified in this
release.</li>
<li><strong>Action Required:</strong> If you rely on env-based proxy
behaviour or CJS resolution edge-cases, validate your integration after
upgrade (notably <code>proxy-from-env</code> v2 alignment and
<code>main</code> entry compatibility fix).</li>
</ul>
<h2>🚀 New Features</h2>
<ul>
<li><strong>Runtime Features:</strong> No new end-user features were
introduced in this release.</li>
<li><strong>Test Coverage Expansion:</strong> Added broader smoke/module
test coverage for CJS and ESM package usage. (<a
href="https://redirect.github.com/axios/axios/pull/7510">#7510</a>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li><strong>Headers:</strong> Trim trailing CRLF in normalised header
values. (<a
href="https://redirect.github.com/axios/axios/pull/7456">#7456</a>)</li>
<li><strong>HTTP/2:</strong> Close detached HTTP/2 sessions on timeout
to avoid lingering sessions. (<a
href="https://redirect.github.com/axios/axios/pull/7457">#7457</a>)</li>
<li><strong>Fetch Adapter:</strong> Cancel <code>ReadableStream</code>
created during request-stream capability probing to prevent async
resource leaks. (<a
href="https://redirect.github.com/axios/axios/pull/7515">#7515</a>)</li>
<li><strong>Proxy Handling:</strong> Fixed env proxy behavior with
<code>proxy-from-env</code> v2 usage. (<a
href="https://redirect.github.com/axios/axios/pull/7499">#7499</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h2>v1.15.0 — April 7, 2026</h2>
<p>This release delivers two critical security patches targeting header
injection and SSRF via proxy bypass, adds official runtime support for
Deno and Bun, and includes significant CI security hardening.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li>
<p><strong>Header Injection (CRLF):</strong> Rejects any header value
containing <code>\r</code> or <code>\n</code> characters to block CRLF
injection chains that could be used to exfiltrate cloud metadata (IMDS).
Behavior change: headers with CR/LF now throw <code>&quot;Invalid
character in header content&quot;</code>. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10660">#10660</a></strong>)</p>
</li>
<li>
<p><strong>SSRF via <code>no_proxy</code> Bypass:</strong> Introduces a
<code>shouldBypassProxy</code> helper that normalises hostnames (strips
trailing dots, handles bracketed IPv6) before evaluating
<code>no_proxy</code>/<code>NO_PROXY</code> rules, closing a gap that
could cause loopback or internal hosts to be inadvertently proxied.
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10661">#10661</a></strong>)</p>
</li>
</ul>
<h2>🚀 New Features</h2>
<ul>
<li><strong>Deno &amp; Bun Runtime Support:</strong> Added full smoke
test suites for Deno and Bun, with CI workflows that run both runtimes
before any release is cut. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10652">#10652</a></strong>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<ul>
<li><strong>Node.js v22 Compatibility:</strong> Replaced deprecated
<code>url.parse()</code> calls with the WHATWG
<code>URL</code>/<code>URLSearchParams</code> API across examples,
sandbox, and tests, eliminating <code>DEP0169</code> deprecation
warnings on Node.js v22+. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li>
</ul>
<h2>🔧 Maintenance &amp; Chores</h2>
<ul>
<li>
<p><strong>CI Security Hardening:</strong> Added <a
href="https://github.com/zizmorcore/zizmor">zizmor</a> GitHub Actions
security scanner; switched npm publish to OIDC Trusted Publishing
(removing the long-lived <code>NODE_AUTH_TOKEN</code>); pinned all
action references to full commit SHAs; narrowed workflow permissions to
least privilege; gated the publish step behind a dedicated
<code>npm-publish</code> environment; and blocked the sponsor-block
workflow from running on forks. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10618">#10618</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10619">#10619</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10627">#10627</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10637">#10637</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10641">#10641</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10666">#10666</a></strong>)</p>
</li>
<li>
<p><strong>Docs:</strong> Clarified HTTP/2 support and the unsupported
<code>httpVersion</code> option; added documentation for header case
preservation; improved the <code>beforeRedirect</code> example to
prevent accidental credential leakage. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10644">#10644</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10654">#10654</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>)</p>
</li>
<li>
<p><strong>Dependencies:</strong> Bumped <code>picomatch</code>,
<code>handlebars</code>, <code>serialize-javascript</code>,
<code>vite</code> (×3), <code>denoland/setup-deno</code>, and 4
additional dev dependencies to latest versions. (<strong><a
href="https://redirect.github.com/axios/axios/issues/10564">#10564</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10565">#10565</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10567">#10567</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10568">#10568</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10572">#10572</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10574">#10574</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10663">#10663</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10664">#10664</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10665">#10665</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10669">#10669</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10670">#10670</a></strong>)</p>
</li>
</ul>
<h2>🌟 New Contributors</h2>
<p>We are thrilled to welcome our new contributors. Thank you for
helping improve axios:</p>
<ul>
<li><strong><a
href="https://github.com/Kilros0817"><code>@​Kilros0817</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li>
<li><strong><a
href="https://github.com/shaanmajid"><code>@​shaanmajid</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10616">#10616</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10617">#10617</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10618">#10618</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10619">#10619</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10637">#10637</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10641">#10641</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10666">#10666</a></strong>)</li>
<li><strong><a
href="https://github.com/ashstrc"><code>@​ashstrc</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>,
<strong><a
href="https://redirect.github.com/axios/axios/issues/10644">#10644</a></strong>)</li>
<li><strong><a
href="https://github.com/Abhi3975"><code>@​Abhi3975</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10589">#10589</a></strong>)</li>
<li><strong><a
href="https://github.com/raashish1601"><code>@​raashish1601</code></a></strong>
(<strong><a
href="https://redirect.github.com/axios/axios/issues/10573">#10573</a></strong>)</li>
</ul>
<p><a
href="https://github.com/axios/axios/compare/v1.14.0...v1.15.0">Full
Changelog</a></p>
<hr />
<h2>v1.14.0 — March 27, 2026</h2>
<p>This release fixes a security vulnerability in the
<code>formidable</code> dependency, resolves a CommonJS compatibility
regression, hardens proxy and HTTP/2 handling, and modernises the build
and test toolchain.</p>
<h2>🔒 Security Fixes</h2>
<ul>
<li><strong>Formidable Vulnerability:</strong> Upgraded
<code>formidable</code> from v2 to v3 to address a reported
arbitrary-file vulnerability. Updated test server and assertions to
align with the v3 API. (<strong><a
href="https://redirect.github.com/axios/axios/issues/7533">#7533</a></strong>)</li>
</ul>
<h2>🐛 Bug Fixes</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="772a4e54ec"><code>772a4e5</code></a>
chore(release): prepare release 1.15.0 (<a
href="https://redirect.github.com/axios/axios/issues/10671">#10671</a>)</li>
<li><a
href="4b071371be"><code>4b07137</code></a>
chore(deps-dev): bump vite from 8.0.0 to 8.0.5 in /tests/smoke/esm (<a
href="https://redirect.github.com/axios/axios/issues/10663">#10663</a>)</li>
<li><a
href="51e57b39db"><code>51e57b3</code></a>
chore(deps-dev): bump vite from 8.0.2 to 8.0.5 (<a
href="https://redirect.github.com/axios/axios/issues/10664">#10664</a>)</li>
<li><a
href="fba1a77930"><code>fba1a77</code></a>
chore(deps-dev): bump vite from 8.0.2 to 8.0.5 in /tests/module/esm (<a
href="https://redirect.github.com/axios/axios/issues/10665">#10665</a>)</li>
<li><a
href="0bf6e28eac"><code>0bf6e28</code></a>
chore(deps): bump denoland/setup-deno in the github-actions group (<a
href="https://redirect.github.com/axios/axios/issues/10669">#10669</a>)</li>
<li><a
href="8107157c57"><code>8107157</code></a>
chore(deps-dev): bump the development_dependencies group with 4 updates
(<a
href="https://redirect.github.com/axios/axios/issues/10670">#10670</a>)</li>
<li><a
href="e66530e330"><code>e66530e</code></a>
ci: require npm-publish environment for releases (<a
href="https://redirect.github.com/axios/axios/issues/10666">#10666</a>)</li>
<li><a
href="49f23cbfe4"><code>49f23cb</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/10668">#10668</a>)</li>
<li><a
href="363185461b"><code>3631854</code></a>
fix: unrestricted cloud metadata exfiltration via header injection chain
(<a
href="https://redirect.github.com/axios/axios/issues/10">#10</a>...</li>
<li><a
href="fb3befb6da"><code>fb3befb</code></a>
fix: no_proxy hostname normalization bypass leads to ssrf (<a
href="https://redirect.github.com/axios/axios/issues/10661">#10661</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v1.13.2...v1.15.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by [GitHub Actions](<a
href="https://www.npmjs.com/~GitHub">https://www.npmjs.com/~GitHub</a>
Actions), a new releaser for axios since your current version.</p>
</details>
<details>
<summary>Install script changes</summary>
<p>This version modifies <code>prepare</code> script that runs during
installation. Review the package contents before updating.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=1.13.2&new-version=1.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/CherryHQ/cherry-studio/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-16 14:36:26 +08:00
fullex
04b18ab7f4 merge main into v2 2026-04-15 23:06:58 -07:00
fullex
bf3235be8e fix(selection): upgrade electron to 41.2.1 and drop resize workaround
Electron v40.8.3 (PR electron/electron#50301, backport of #49428) fixed
the transparent + frameless window resize regression on Windows tracked
as electron/electron#48554. The Windows-only manual resize workaround
(custom 8-direction ResizeHandle + IPC + setBounds) is no longer needed.

- Bump electron 40.8.0 -> 41.2.1 (latest stable)
- Remove SelectionService.resizeActionWindow and its IPC handler
- Remove ResizeHandle component, handleResizeStart and ResizeDirection
  type from SelectionActionApp; trim ReactMouseEvent and isWin imports
- Remove preload resizeActionWindow bridge
- Remove Selection_ActionWindowResize IPC channel

Native resize now works uniformly across Windows/macOS/Linux.

Signed-off-by: fullex <0xfullex@gmail.com>
2026-04-15 22:38:21 -07:00
fullex
1fd54832e1 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-11 18:37:58 -07:00
beyondkmp
e54cfe97ea fix(agents): set NODE_PATH so spawned Claude Code process can resolve @img/sharp (#14183)
### What this PR does

Before this PR:
The forked Claude Agent SDK child process (`cli.js`) runs from
`asar.unpacked` but cannot resolve native modules like `@img/sharp` that
also live in `asar.unpacked`, because Node's module resolution doesn't
search that directory by default.

After this PR:
Injects `NODE_PATH` pointing to the `asar.unpacked/node_modules`
directory into the child process environment, so Node's module
resolution finds `@img/sharp` and other native modules correctly.

### Why we need it and why it was done in this way

The child process is forked via `node:child_process.fork()` with
`ELECTRON_RUN_AS_NODE=1`. Its module resolution starts from the SDK's
location inside `asar.unpacked` but doesn't automatically search sibling
`node_modules` at the unpacked root. Setting `NODE_PATH` is the standard
Node.js mechanism to add extra module search paths without patching
module internals.

The following alternatives were considered:
- Patching `Module._resolveFilename` via a `--require` bootstrap — more
invasive, harder to maintain.
- Symlinking sharp into the SDK's own `node_modules` in `before-pack.js`
— fragile across platforms.

### 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: beyondkmp <beyondkmp@gmail.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: suyao <sy20010504@gmail.com>
2026-04-12 00:39:56 +08:00
kangfenmao
bd61bad7ee chore: release v1.9.1 2026-04-11 15:32:27 +08:00
fullex
8f9bf0b516 fix(data): patch @libsql/client to replay PRAGMAs after transaction()
`Sqlite3Client.transaction()` nullifies its internal connection
(`this.#db = null`), causing the next operation to create a new
connection with default PRAGMAs. This resets `synchronous` from
NORMAL back to FULL — roughly 2x write performance degradation.

Patch `@libsql/client@0.15.15` to add `setPragma()` which registers
per-connection PRAGMAs and replays them in `#getDb()` and `reconnect()`
whenever a new connection is created. Pattern borrowed from upstream
PR #328's ATTACH replay mechanism.

Update DbService and MigrationDbService to use `createClient()` +
`setPragma()` instead of `db.run(sql\`PRAGMA ...\`)` for per-connection
settings.

Upstream issues (still open, no official fix):
- tursodatabase/libsql-client-ts#229
- tursodatabase/libsql-client-ts#288

Signed-off-by: fullex <0xfullex@gmail.com>
2026-04-10 08:21:49 -07:00
槑囿脑袋
798a15e919 feat(v2): knowledge service backend (#14090)
Co-authored-by: SuYao <sy20010504@gmail.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-04-10 21:24:06 +08:00
jidan745le
780a884c67 feat(data): provider/model data migration and registry service (backend only) (#14115)
### What this PR does

Before this PR:
- v2 migration did not include provider/model data migration from legacy
`llm` state.
- Provider/model data APIs and handlers were incomplete.
- `@cherrystudio/provider-registry` (formerly provider-catalog) package
was not integrated into the data layer.

After this PR:
- Add provider/model migration path (`ProviderModelMigrator` + mappings)
and register it in v2 migrator flow.
- Add `@cherrystudio/provider-registry` package with JSON-based registry
data, Zod-validated schemas, and lifecycle-managed
`ProviderRegistryService`.
- Complete provider/model schemas, services, handlers, shared API
schemas/types, and model merger utility.
- Complete provider API endpoints (`registry-models`, `auth-config`,
`api-keys`) aligned with lifecycle DI patterns.

**Note:** This PR is intentionally scoped to backend/data-layer only.
Renderer consumer migration will be submitted in a separate PR to
maintain domain separation.

Fixes #

N/A

### Why we need it and why it was done in this way

The following tradeoffs were made:
- Kept migration and data API implementation within current v2
architecture (handler -> service -> db schema) instead of adding
temporary compatibility layers.
- Replaced protobuf toolchain with JSON + Zod validation for simpler
data pipeline and better debuggability.
- Converted all numeric enums to string-valued `as-const` objects
(EndpointType, ModelCapability, Modality, etc.) for runtime
debuggability.
- Unified separate `baseUrls`, `modelsApiUrls`, `reasoningFormatTypes`
fields into a single `endpointConfigs` map keyed by EndpointType.

The following alternatives were considered:
- Keep protobuf-based registry data; rejected due to complexity of proto
toolchain and poor debuggability of binary data.
- Include renderer consumer migration in same PR; deferred to separate
PR for cleaner domain boundaries.

Links to places where the discussion took place:
- Original combined PR: #14034

### Breaking changes

None.

### Special notes for your reviewer

- This is a backend-only extraction from #14034, which contained both
backend and renderer consumer code. The renderer migration will follow
in a separate PR.
- Please focus review on migration flow (`ProviderModelMigrator`),
provider/model service contracts, and the registry package design.
- The `@cherrystudio/provider-registry` package was renamed from
`provider-catalog` and uses JSON data files instead of protobuf.

### 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 data layer, no user-facing
changes)
- [x] Self-review: I have reviewed my own code

### Release note

```release-note
NONE
```

---------

Signed-off-by: jidan745le <420511176@qq.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-04-10 19:12:33 +08:00
fullex
6541948556 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-09 23:23:32 -07:00
亢奋猫
45463362c9 hotfix(analytics): track token usage with source distinction for chat and agent (#14149)
### What this PR does

Before this PR:
- Token usage tracking was missing for mini window, selection action
window, and translate service (they call `fetchChatCompletion` but don't
go through `baseCallbacks`)
- Agent session token usage was not distinguished from regular chat
usage
- `baseCallbacks.ts` and `TranslateService.ts` had duplicate tracking
that was redundant with `fetchChatCompletion`

After this PR:
- All `fetchChatCompletion` callers (chat, translate, mini window,
selection action) are automatically tracked with `source: 'chat'`
- Agent sessions are tracked in `baseCallbacks` with `source: 'agent'`
- No duplicate tracking; each code path is tracked exactly once
- Upgraded `@cherrystudio/analytics-client` to 1.3.0 with native
`source` field support

### Why we need it and why it was done in this way

Token usage analytics were incomplete — several code paths that consume
tokens were not being tracked. Additionally, there was no way to
distinguish whether token usage came from regular chat or agent
sessions.

The following tradeoffs were made:
- Tracking is done via `onChunk` wrapper in `fetchChatCompletion` rather
than requiring each caller to manually track, preventing future
omissions
- Agent tracking stays in `baseCallbacks` because agent sessions use
`createAgentMessageStream` directly and bypass `fetchChatCompletion`

The following alternatives were considered:
- Adding tracking to each individual caller — rejected because it's
error-prone and led to the current missing coverage

### Breaking changes

None.

### Special notes for your reviewer

- `fetchChatCompletion` now wraps `onChunk` to intercept
`BLOCK_COMPLETE` and track usage — this covers chat, translate, mini
window, and selection action
- `baseCallbacks.ts` only tracks agent sessions (guarded by
`isAgentSessionTopicId`) to avoid double-counting with
`fetchChatCompletion`
- The `source` field is `optional` in
`@cherrystudio/analytics-client@1.3.0`, defaulting to `'chat'`

### 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
NONE
```

Signed-off-by: kangfenmao <kangfenmao@qq.com>
2026-04-10 10:42:00 +08:00
亢奋猫
af2a16a01a chore: release v1.9.0 (#14142)
### What this PR does

This is a release PR for version 1.9.0. It updates the version number
and release notes.

Before this PR:
- Version was set to 1.9.0-rc.0 (release candidate)
- Release notes contained RC-specific content

After this PR:
- Version is now 1.9.0 (stable release)
- Release notes updated with all bug fixes and improvements since RC

### Why we need it and why it was done in this way

This marks the official 1.9.0 stable release after the RC testing
period. The release includes all bug fixes committed after 1.9.0-rc.0.

### Breaking changes

None. This is a version bump from RC to stable.

### Special notes for your reviewer

**Included commits (since v1.9.0-rc.0):**
- fix(models): add Ollama gemma4 format support for capability detection
(#14036)
- hotfix(mcp): preserve multi-element hub tool results (#14116)
- fix: optimize agent bootstrap startup time (~1.6s → ~270ms) (#14098)
- hotfix(channels): toggle single channel no longer reconnects all
channels (#14112)
- fix: prevent data loss when selecting model via keyboard shortcut
(#14130)
- fix: restore rich editor search state and scrolling (#14117)
- fix(ci): restore missing Linux build dependencies in nightly workflow
(#14105)
- hotfix(build): include resources directory files excluded by glob
pattern (#14121)
- fix(agents): remove conflicting language instruction from Cherry
Assistant (#14076)
- hotfix(think): MiMo thinking toggle (#14109)
- hotfix(renderer): rendering issue of the unescaped '|' in <sup> within
Markdown tables. (#14092)

### 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
See release notes in electron-builder.yml for full details.

Key fixes since RC:
- [Models] Add Ollama gemma4 format support for Gemma 4 model capability detection
- [MCP] Fix Hub-mode MCP tool calls silently truncating list-style responses
- [Chat] Fix data loss when selecting model via keyboard shortcut
- [Notes] Fix note editor search state and scrolling
- [Build] Fix built-in skill files (.md) missing from packaged app
- [Agents] Fix Cherry Assistant ignoring user's language
- [Models] Fix Xiaomi MiMo thinking/non-thinking toggle behavior
```

Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-09 21:51:43 +08:00
亢奋猫
a83f98fd24 docs: consolidate bilingual docs, add link checker and architecture overview (#14138)
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-04-09 16:01:40 +08:00
亢奋猫
2e7b605b5b chore: release v1.9.0-rc.0 (#13987)
### What this PR does

This is a release PR for Cherry Studio v1.9.0-rc.0.

**Changes included:**
- Bumped version from 1.8.4 to 1.9.0-rc.0
- Updated bilingual release notes in `electron-builder.yml`

**Release Notes Summary:**

 New Features
- CherryClaw autonomous agent type with personality-driven scheduling,
Telegram integration, and sandbox mode
- Terminal-style syntax highlighting for shell tool outputs
- Flomo MCP integration for note capture
- rtk token optimization (60-90% reduction) for agent shell commands
- Improved agent tool rendering with syntax-highlighted diffs and file
icons
- AI-powered error diagnosis with classification and guided resolution
- Topics list now respects pinTopicsToTop setting
- Added endpoint option for aionly provider

🐛 Bug Fixes
- new-api provider now uses configured host for Anthropic format
requests
- Claude Code sessions now respect proxy settings for child processes
- Code tool validates working directory before launch
- Fixed epub embedding failure
- Fixed KaTeX backslash corruption in Notes editor
- Fixed thinking time display race condition
- Fixed Poe provider model loading
- Fixed kimi-cli crash when uv binary not found
- Fixed invalid env variable names for providers with dots in name
- Fixed NVIDIA provider reasoning parameters for
Qwen/DeepSeek/Kimi/Zhipu
- Fixed Google Gemini web search for API-fetched models
- Fixed Qwen3.5 model detection for 3.9 series
- Fixed backup file size regression

💄 Improvements
- Fixed macOS traffic light alignment

 Performance
- Optimized backup compression level for faster backups

### Checklist

- [x] Review generated release notes in `electron-builder.yml`
- [x] Verify version bump in `package.json`
- [ ] CI passes
- [ ] Merge to trigger release build

### Included Commits

52 commits since v1.8.4, including:
- feat(agents): add CherryClaw autonomous agent type (#13359)
- feat: add AI-powered error diagnosis and guided resolution (#13894)
- feat: integrate rtk for reducing LLM token consumption (#13615)
- feat(mcp): add flomo built-in server (#13928)
- fix: resolve CherryIN supported_endpoint_types not being detected
- fix: use configured host for new-api anthropic format requests
(#13724)
- fix(agents): route Claude Code child process through proxies (#13895)
- fix: migrate epub to v2 async api (#13939)
- fix(notes): prevent KaTeX backslash corruption (#13910)
- fix(ThinkingBlock): prevent race condition in thinking time display
(#13934)
- fix(models): strip `models/` prefix from Google API model IDs (#13861)
- perf(backup): adjust compression level for speed optimization (#13882)
- And 40 more bug fixes and improvements

---------

Co-authored-by: SuYao <sy20010504@gmail.com>
2026-04-03 18:17:52 +08:00
suyao
6b14fcd5ce refactor: bump AI SDK deps and fix provider API host formatting
- Bump @ai-sdk/* packages to latest versions and update patches
- Fix newapi provider: defer API version suffix to build phase so gemini
  endpoints get /v1beta instead of /v1
- Fix Azure provider: split host formatting so azure-anthropic (Claude)
  endpoints don't get the /openai suffix meant for Azure OpenAI
- Re-add @ai-sdk/google getModelPath patch (includes("models/") check)
- Support azure-openai provider type in Claude Code agent service by
  auto-constructing the /anthropic base URL for Claude models

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-03 14:18:02 +08:00