Commit Graph

109 Commits

Author SHA1 Message Date
Pleasurecruise
9d22bce7cc Merge remote-tracking branch 'origin/main' into refactor/code-cli 2026-07-03 15:28:49 +08:00
jd
a1a659e690 feat(sidebar): mixed sidebar list with launchpad ordering decoupled (#16400)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
2026-07-03 11:39:33 +08:00
Gu JiaMing
c881c7f83b feat(conversation-shell): add right pane tab shortcuts (#16662)
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
2026-07-02 19:56:46 +08:00
fullex
9b9570116a refactor(db): replace libsql with better-sqlite3 + sqlite-vec (#16626) 2026-07-02 13:21:13 +08:00
Pleasurecruise
e031d6c37d fix: expand Code CLI integration
Adds IPC schemas/handlers for Code CLI actions, moves launch flow to the new request API, and extends support to Gemini CLI, Qwen Code, Kimi Code, Qoder CLI, and GitHub Copilot CLI. Also updates native config injection/cleanup, provider ordering, and the code tools UI to support providerless launches and the new tool metadata.
2026-07-02 11:56:03 +08:00
Pleasurecruise
84840a21f4 Merge remote-tracking branch 'origin/main' into refactor/code-cli
Signed-off-by: Pleasurecruise <3196812536@qq.com>

# Conflicts:
#	src/shared/data/preference/preferenceSchemas.ts
2026-07-01 14:45:52 +08:00
jd
461e45d133 feat(chat): independent classic/modern layout settings for conversations and work (#16434)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
2026-07-01 11:27:58 +08:00
亢奋猫
366ecf63da refactor(provider): remove tokenflux providers (#16518)
Signed-off-by: kangfenmao <kangfenmao@qq.com>
2026-06-30 19:52:35 +08:00
Phantom
b06aa99399 refactor(file-manager): remove renderer FileManager (#16452)
Signed-off-by: icarus <eurfelux@gmail.com>
Signed-off-by: eurfelux <eurfelux@gmail.com>
2026-06-28 13:38:01 +08:00
Pleasurecruise
c2cea64a20 refactor(code-cli): split main process — persist provider configs to native CLI files, migrate OpenClaw IPC
Main-process half of the code-cli refactor (split from renderer changes).

- Persist provider configs to native CLI config files (claude-code/codex/opencode/hermes/openclaw) instead of launch env vars
- Multi-config per CLI tool (named configs in preference)
- Migrate OpenClaw command IPC to IpcApi (openclaw.*), drop legacy IpcChannel.OpenClaw_* handlers and install-progress broadcast
- Keep OpenClawService syncConfig/resolveSyncConfig logic + install dedup from #16105; only the IPC surface is migrated
- Add per-CLI config writers (claudeCodeConfig/codexConfig/openCodeConfig/hermesConfig/openclawConfig) with unit tests
- Remove v1 CodeCliTransforms migrator + tests
- Add smol-toml/json5/js-yaml deps

Part 1 of 2. Renderer changes land in the stacked follow-up PR.

Signed-off-by: Pleasurecruise <3196812536@qq.com>
2026-06-28 10:03:52 +08:00
fullex
bf5910f424 refactor(shared): clean up @shared residue, single-process residents, barrels, naming
- Drop dead @deprecated LanFileChunk{,Ack}Message types; de-Redux a stale comment
- Relocate single-process modules out of @shared (Invariant 1.1):
  - types/plugin.ts -> main/utils (markdownParser-only)
  - utils/ocr.ts + types/ocr.ts -> renderer (renderer-only; types now standalone)
  - utils/searchSnippet.ts, utils/pdf.ts -> main/utils (main-only)
  - utils/externalApp.ts EXTERNAL_APPS -> inlined into ExternalAppsService
- Convert types/file, utils/file, utils/command, utils/api barrels from
  `export *` to explicit named exports (section 3.1)
- Naming: urlUtil.ts->url.ts; api/utils.ts->api/format.ts (+fold formatApiHost/
  formatOllamaApiHost); hasAPIVersion->hasApiVersion; URLString/FileURLString->
  UrlString/FileUrlString; enum codeCLI->CodeCli, terminalApps->TerminalApp with
  UPPER_SNAKE_CASE members
- Sync docs to the moves/renames; track data/types route-by-shape as an open question
2026-06-27 06:16:26 -07:00
SuYao
c4bae482df feat(read-file): agentic read_file tool for chat attachments (#16257)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-27 18:47:51 +08:00
fullex
32e8ef273c feat(window-manager): add declarative rememberBounds persistence
Migrate window-bounds persistence off the electron-window-state library into
a WindowManager built-in `rememberBounds` capability, backed by the main-process
persist cache (`window.bounds` key — its first real consumer).

- New `windowBoundsTracker` free-function module: validates the stored record
  (including displayBounds), restores onto the display the window was last on
  (clamping into its work area, never resetting to primary), and snapshots at
  teardown via getNormalBounds + isMaximized.
- Singleton-only gate (dev warning for non-singleton types). Runtime toggle
  `wm.setRememberBounds` (orthogonal to the registry flag; OFF drops only that
  type's slot) plus `wm.peekWindowBounds`.
- Persist at three teardown exits: native close (singletons), before
  window.destroy() in destroyWindow (programmatic destroys), and a new onStop
  so shutdown writes land before CacheService flushes its persist map.
- Wire Main + QuickAssistant. Main re-applies maximize consumer-side on its own
  show schedule (tray-on-launch defers to first show); remove electron-window-state
  and its orphaned keepers/constants/comments.

Fullscreen is not persisted and old *-state.json is not migrated (one-time
reset, loseable). Adds tracker/integration/persist tests, extends the main
CacheService mock with persist methods, and documents the capability plus a
breaking-change note.
2026-06-26 22:39:52 -07:00
fullex
ecffd880f0 refactor(store): delete the deprecated v1 Redux store
With ImportService migrated to DataApi (#16415), the v1 Redux store at
src/renderer/store/ has zero runtime consumers. Delete the directory (30
files) along with the already-stubbed main-process ReduxService bridge.

Clean up the now-stale residue:
- Remove dead vi.mock('@renderer/store') factories from 14 test files
  whose code under test no longer imports the store.
- Drop Redux from the CLAUDE.md "Removing" enumerations and refresh the
  renderer-architecture / knowledge-service / v2-todo docs.
- Fix dangling store/ references in the MiniAppMigrator and
  builtinMcpServers comments.

The v2 migration's Redux Persist readers (ReduxStateReader etc.) are left
untouched: they read serialized on-disk data, not this store.
2026-06-26 01:08:20 -07:00
SuYao
e6f70f556f feat(paintings): rebuild prompt bar on the shared composer (#16326)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Pleasurecruise <3196812536@qq.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-25 19:32:32 +08:00
jd
97ec669b8e refactor(chat): remove long paste input settings (#16329)
Signed-off-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
2026-06-25 13:12:38 +08:00
槑囿脑袋
2099f0a109 feat(web-search): default providers and route Jina to its China mirror (#16331)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-06-24 23:01:27 +08:00
LiuVaayne
efecdd5007 refactor(binary-manager): unify CLI binary acquisition behind mise-backed BinaryManager (#15184)
### What this PR does

**Before this PR**, Cherry Studio managed external CLI binaries through
five uncoordinated mechanisms — each requiring its own download script,
IPC channel, and on-disk layout:

| Mechanism | Where it lived | How it worked |
|---|---|---|
| rtk extraction | `src/main/utils/rtk.ts` + `AgentBootstrapService` |
Copies bundled binary to `~/.cherrystudio/bin/` |
| OpenClaw installer | `resources/scripts/install-openclaw.js` |
Downloads from GitHub/mirror with custom extraction |
| CodeCliService | `src/main/services/CodeCliService.ts` | `bun install
-g` to `~/.cherrystudio/install/global/` |
| ripgrep | `node_modules/@anthropic-ai/claude-agent-sdk/vendor/` |
Vendored, hardcoded path in `FileStorage` |
| (old) MiseService | `src/main/services/MiseService.ts` | Bundled mise
+ `mise use -g` |

**After this PR**, a single `BinaryManager` lifecycle service owns all
third-party CLI binary acquisition. It wraps
[mise](https://mise.jdx.dev) as the only acquisition backend (no custom
`BinaryBackend` interface — mise's polyglot grammar already covers
`npm:`, `pipx:`, `github:`, registry entries). Tools install into an
isolated environment under `~/.cherrystudio/mise/` so user-level mise
installs are never touched. `uv`, `bun`, `rg`, and mise itself ship
bundled at build time for instant first-run availability; everything
else flows through mise on demand.

<img width=\"1304\" height=\"714\" alt=\"BinaryManager settings UI\"
src=\"https://github.com/user-attachments/assets/7a4b78ab-5aa2-4e97-9ab7-134b20a4d78d\"
/>
<img width=\"1165\" height=\"748\" alt=\"Three-state managed vs bundled
vs not-installed\"
src=\"https://github.com/user-attachments/assets/a0dcfb7d-8bc3-4acd-b563-0fc04d99e252\"
/>
<img width=\"523\" height=\"328\" alt=\"Custom tool dialog\"
src=\"https://github.com/user-attachments/assets/90c3ee95-7f2a-4daf-a334-f20de6ff5ca2\"
/>

Fixes #15183. Addresses #15370.

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

Adding a new managed CLI tool should be a one-line preset entry — not 4+
files of bespoke download/extract/IPC code. mise is a mature polyglot
tool manager that already speaks the backends Cherry needs.

**Tradeoffs made:**
- **mise bundled at build time** (~15 MB per platform) rather than
downloaded at first run — faster first-run UX, no chicken-and-egg on a
fresh install.
- **Fully isolated mise environment** (\`HOME\`/\`XDG_*\`/\`MISE_*\` all
relocated under \`feature.binaries.data\`) — Cherry never reads or
writes the user's own \`~/.config/mise/\` or \`~/.local/share/mise/\`.
- **No custom \`BinaryBackend\` interface.** mise's grammar (\`npm:\`,
\`pipx:\`, \`github:\`, registry) is already polyglot; wrapping it would
be a shallow seam that re-implements what mise owns. Removing this
abstraction makes consumers simpler (deletion test passes).
- **Auth-token policy: opt-in only.** Ambient \`GITHUB_TOKEN\` /
\`GH_TOKEN\` are not forwarded into mise's process env. Users who hit
GitHub's unauthenticated 60 req/hr API limit can set
\`CHERRY_GITHUB_TOKEN\` to raise it to 5000 req/hr without consenting to
share their general shell token.
- **China mirror auto-detection.** \`isUserInChina()\` toggles
\`NPM_CONFIG_REGISTRY=registry.npmmirror.com\` +
\`PIP_INDEX_URL=pypi.tuna.tsinghua.edu.cn\` for every npm/pipx backend
transparently.

**Alternatives considered:**
- *Keep per-tool install scripts.* Doesn't scale — each new tool is 4+
files of duplicated logic.
- *Use mise from user's \`PATH\`.* Would depend on user having mise
installed and could conflict with their config.
- *Custom \`BinaryBackend\` abstraction.* Shallow wrapper over mise's
grammar; no second backend in sight; deletion test passes.

**Scope (what's in / what's out):**
- **In:** uv, bun, ripgrep, claude-code, openclaw, gh, opencode,
gemini-cli, lark, kimi-cli, qwen-code, iflow-cli, github-copilot-cli —
anything mise can install as a single relocatable binary.
- **Out:** \`OvmsManager\` (multi-file server provisioning, hardware
detection, generated config); Tesseract OCR data (not a binary; lives
with \`OvOcrService\`).

### Breaking changes

None at the user-facing layer. v2 data is throwaway per CLAUDE.md, so
the preference-key rename (\`feature.mise.*\` → \`feature.binaries.*\`)
intentionally ships without a migrator.

### Special notes for your reviewer

**Architecture & docs**
- \`docs/references/binary-manager/README.md\` — scope criterion,
persisted/contract surface, bundled-vs-mise state contract, China mirror
behavior, \`CHERRY_GITHUB_TOKEN\` opt-in, adding a new managed binary.
- \`CLAUDE.md\` adds a \`**MUST READ**\` link next to Lifecycle / Window
Manager / Data / Paths.
- The mise-shim-wins-over-\`cherry.bin\` precedence rule is documented
in the README's "State contract" section.

**Code orientation**
- \`src/main/services/BinaryManager.ts\` — the lifecycle service. Wraps
mise via \`runMise()\`; isolated env in \`buildIsolatedEnv()\`; bundled
extraction with atomic tmp+rename; per-tool try/catch so a single
failure can't abort init; \`isManagedBinaryReady()\` verifies the
resolved file is executable (not just that mise thinks it's installed).
- \`packages/shared/data/presets/binary-tools.ts\` —
\`PREDEFINED_BINARY_TOOLS\` registry; \`tool\` field is a mise spec.
-
\`src/renderer/src/pages/settings/McpSettings/EnvironmentDependencies.tsx\`
— three-state UI (\`managed\` / \`bundled\` / \`not-installed\`) backed
by \`Binary_GetState\` + \`Binary_ProbeBundled\`.
- \`scripts/download-binaries.js\` — build-time downloader for mise / uv
/ bun / rg (HTTPS + sha256-verified, archive-aware extraction).

**Migration**
- \`OpenClawService.install()\` is now two lines delegating to
\`BinaryManager\` — \`install-openclaw.js\` is gone.
- \`CodeCliService\` no longer uses \`bun install -g\`; the
\`BUN_INSTALL\` / \`~/.cherrystudio/install/global/\` path is removed.
- \`FileStorage.getRipgrepBinaryPath()\` now resolves via
\`getBinaryPath('rg')\`; the vendored SDK rg is no longer used.
- \`extractRtkBinaries\` + the \`AgentBootstrapService\` call are
deleted. \`rtkRewrite()\` degrades gracefully when rtk is absent;
\`rtkAvailable\` caches with a 60s TTL so install-via-mise takes effect
without restart.

**Multi-round review**
Two adversarial review rounds against this branch (Bug Hunter / Security
/ Architecture / Correctness) ran during development; both rounds'
High-severity findings are addressed in commits \`70afde6af\` and
\`1d864439d\`. R3 known follow-ups (architecture duplications in
\`CodeCliService\`'s switch statements, etc.) are tracked as Medium and
intentionally deferred.

### 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: Leaves binary acquisition meaningfully cleaner than
before (five mechanisms → one)
- [x] Upgrade: v2 data is throwaway; no migrator needed and the absence
is intentional
- [x] Documentation: \`docs/references/binary-manager/README.md\` +
\`CLAUDE.md\` Architecture section
- [x] Self-review: Two multi-perspective review rounds against the
branch; all Highs addressed

### Release note

\`\`\`release-note
NONE
\`\`\`

---------

Signed-off-by: Vaayne <liu.vaayne@gmail.com>
Signed-off-by: Vaayne Liu <vaayne@macos.shared>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-06-24 15:15:25 +08:00
fullex
4dc36fa20f feat(power): elevate PowerMonitorService into a system power hub
Rename PowerMonitorService -> PowerService and relocate it to
src/main/core/power/, turning the shutdown-only service into a complete,
self-contained power hub:

- Typed power events (suspend/resume/lock/unlock/power-source) with
  suspend/resume + power-source de-duplication; lock/unlock pass-through.
- Bounded, cross-platform shutdown barrier: preventDefault on macOS/Linux,
  blockShutdown via a minimal hidden window on Windows; handlers run under a
  5s hard timeout, then the app quits through the normal quit flow.
- Best-effort, ref-counted sleep prevention: preventSleep(reason) returns a
  Disposable and never throws (the provider degrades internally). The OS
  blocker engages only while a hold is held AND the user enabled
  app.power.prevent_sleep_when_busy. JobManager is the first registrant,
  acquiring a hold per execution attempt.

Add the app.power.prevent_sleep_when_busy preference (v2-only, no v1 source)
and a Settings -> General toggle. Service phase moved Background -> WhenReady.
2026-06-23 06:29:23 -07:00
SuYao
32a6666bb3 chore(chat-page): scaffold chat component tree (#14997)
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: kangfenmao <kangfenmao@qq.com>
Co-authored-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Signed-off-by: kangfenmao <kangfenmao@qq.com>
Signed-off-by: jdzhang <625013594@qq.com>
Signed-off-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
2026-06-23 20:31:49 +08:00
Gu JiaMing
02b1373218 fix(file-processing): route image OCR through file processing (#16125)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
Signed-off-by: 顾家铭 <gujiaming@gujiamingdeMacBook-Pro.local>
2026-06-22 21:21:27 +08:00
fullex
1c6ff30a18 refactor(shared): dissolve config/ and move logic out of types/ into utils/
Dissolve the by-kind @shared/config junk drawer per shared-layer governance: route each member by shape and actual consumer process — cross-process slices into types//utils//ai/, single-process code back into main/renderer (Invariant 1.1). Confirm each item's real consumer process rather than trusting the directional plan (API_SERVER_DEFAULTS is renderer-only, MIN_WINDOW_* is cross-process, providers.ts is renderer-only), and drop dead consts (ZOOM_LEVELS/ZOOM_OPTIONS, bookExts, thirdPartyApplicationExts).

Purge runtime logic from types/ so the bucket holds only declarations: move serializeError + AI-SDK error guards to utils/error.ts, the FileHandle factories/guards to utils/file/handle.ts, isSerializable + SerializableSchema to utils/serializable.ts, and the tab-instance guard/normalizer to utils/tabInstanceMetadata.ts. Tests follow the logic to utils/__tests__; the type-level ipc contract test is retired (its invariants kept as a breadcrumb for the future IpcApi Zod schema). types/ is now logic-free and test-free.

Also: remove the dead @shared mock from the packages/ui code-editor test so packages/ui no longer references production code; fix the data-classify preference generator prompts import and the update-languages output path to the relocated modules.

Update shared-layer-architecture (3.1 type/util test rule, 5/6 config dissolution) and renderer-architecture cross-references.
2026-06-19 20:41:18 -07:00
SuYao
bef4fc6cd4 feat(renderer-components): split unified Selector component (#16187)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-19 17:05:48 +08:00
Pleasure1234
1714004f83 feat(code-cli): replace discontinued iFlow CLI with Qoder CLI (#16119)
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: Pleasurecruise <3196812536@qq.com>
2026-06-18 16:10:13 +08:00
槑囿脑袋
407b07652d feat(knowledge): re-attribute v1 directory vectors to per-file children on v2 migration (#16093) 2026-06-18 14:00:55 +08:00
fullex
714c1a3dd3 docs(data): add database-construction reference and consolidate migration/custom-SQL/FTS docs
Add docs/references/data/database-construction.md as the single home for how the SQLite DB is built and evolved: boot init order, drizzle migrations (regenerate-never-rename, CI gates, additive-vs-rebuild), the CUSTOM_SQL_STATEMENTS every-boot replay (~0.1ms O(1)), and the FTS5 fts_rowid rowid-stability rule, plus a gotchas table. Move the Migrations and Custom SQL sections out of database-patterns.md into it (left as pointers), and index it from data/README.md and src/main/data/db/README.md.

Fix stale references found while consolidating: wrong generate command, customSql.ts vs customSqls.ts, columnHelpers.ts vs _columnHelpers.ts, a nonexistent messageFts.ts, yarn vs pnpm, the v2-todo single-0000 claim, the generated-column wording, and v1 data.blocks vocabulary in the testing doc.
2026-06-17 05:52:01 -07:00
SuYao
6c61f33c18 feat(data-api): per-topic virtual-root message tree (structural single-root invariant) (#15951)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Signed-off-by: jdzhang <625013594@qq.com>
2026-06-17 18:20:35 +08:00
SuYao
c5b150a21e feat(data-migration): agent/chat/preference v2 migration mappings (#16066)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: jdzhang <625013594@qq.com>
2026-06-16 21:39:35 +08:00
fullex
f6c74a40d1 chore(data-classify): retire non-generate scripts and commands
The data-classification extract/validate/check workflow has completed its
staged mission; only the code-generation pipeline remains in use.

- package.json: replace extract/validate/validate:gen/check:duplicates/all
  with an echo notice; keep generate and generate:* intact
- rename the four retired scripts with a DO-NOT-USE- prefix (git mv)
- README: document the deprecation via a global notice, a status column on
  the command table, renamed file references, and historical-section markers
2026-06-16 05:15:47 -07:00
槑囿脑袋
20035a83ff feat(knowledge): engine-portable per-base index store and retrieval cutover (#15973)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-06-15 19:43:10 +08:00
SuYao
b04f021613 feat(assistant-data): default assistant bootstrap and ordering (#15943)
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Signed-off-by: jdzhang <625013594@qq.com>
2026-06-12 19:46:42 +08:00
SuYao
344b40ac96 feat(ai-stream): stream steer queue (#15935)
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Signed-off-by: jdzhang <625013594@qq.com>
2026-06-12 15:42:27 +08:00
SuYao
eae9716ffa feat(agent-data): agent resource API + agent workspace DataApi workflow (#15941)
Co-authored-by: jd <59188306+zhangjiadi225@users.noreply.github.com>
Co-authored-by: jdzhang <625013594@qq.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
Signed-off-by: jdzhang <625013594@qq.com>
2026-06-11 23:52:31 +08:00
Gu JiaMing
8191c13c8e feat(provider-settings): auto-enable providers when models are available (#15686)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Asurada <43401755+ousugo@users.noreply.github.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
2026-06-10 12:11:11 +08:00
槑囿脑袋
94b7641898 fix(knowledge-migration): preserve v1 vector DB during v2 migration (#15843)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-06-09 21:06:33 +08:00
jd
29286cad38 refactor(agent-session): make workspace binding explicit (#15736)
Co-authored-by: SuYao <sy20010504@gmail.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: jdzhang <625013594@qq.com>
Signed-off-by: zhangjiadi225 <625013594@qq.com>
2026-06-09 17:50:31 +08:00
槑囿脑袋
1382a8dd7c feat(knowledge): route embeddings and reranking through the AI service (#15796)
### What this PR does

Before this PR:

- Knowledge embeddings and reranking ran through the legacy
embedjs-based
knowledgeV1 stack with their own provider clients, independent of the
app's
  AI service.
- File-processing intake accepted several heterogeneous input shapes,
and
knowledge file items were tracked by FileEntry ids, coupling file
content to
  the file-manager entry/cache.

After this PR:

- Embeddings and reranking are routed through the unified `AiService`
(with
cherryin rerank support) and guarded by strict embedding-dimension
validation
  that rejects stale/mismatched vectors.
- File-processing intake is collapsed to a single path-based model;
knowledge
  file items are stored by base-relative path under the knowledge-base
directory, and v1 uploads are copied into the v2 base dir during
migration so
  migrated items stay reindexable/restorable.
- Legacy `knowledgeV1` is removed; the orchestration services were
renamed to
  `KnowledgeService` / `FileProcessingService`.
- Chat -> knowledge attach is temporarily disconnected (tracked TODO)
while the
  v2 file-manager bridge is rebuilt.

Fixes #N/A (no linked issue)

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

Routing embeddings/rerank through `AiService` unifies provider handling
and
credentials and removes the parallel embedjs client stack and its v1
coupling.
Storing knowledge files by base-relative path (instead of FileEntry ids)
makes
each knowledge base self-contained and portable.

The following tradeoffs were made:

- A large, coordinated refactor plus a migration step that physically
copies v1
uploads into the v2 base dir, in exchange for removing the parallel
client
  stack and making bases self-contained.
- Base-relative path storage required a fail-fast/dedup strategy for
same-named
  files and a guard for blank legacy filenames.

The following alternatives were considered:

- Keeping the embedjs stack behind an adapter — rejected; perpetuates
the
  parallel client and v1 coupling.
- Keeping FileEntry-id storage — rejected; couples knowledge files to
the
  file-manager cache and blocks portability.

### Breaking changes

- `knowledgeV1` is removed. Legacy v1 knowledge data reaches v2 only
through the
  v2 migrators; there is no v1 fallback.
- The v2 knowledge HTTP API (API gateway) now returns v2-native
per-entry fields
(`embeddingModelId`, `createdAt` on base entries; `chunkId`,
`scoreKind`,
  `rank` on search results). The response envelope (`knowledge_bases`,
  `searched_bases`, `total`) is unchanged. See

`v2-refactor-temp/docs/breaking-changes/2026-06-05-knowledge-api-v2.md`.

### Special notes for your reviewer

- This branch went through several rounds of multi-agent code review.
The most
recent 6 commits address review findings: directory-import path
collisions,
migrated-file source copying + blank `relativePath` guard, addItems
rollback
error preservation, eager `document_to_markdown` output-target
validation, a
`CompletedKnowledgeBase` type guard, and breaking-changes doc
corrections.
- Chat -> knowledge attach is intentionally disconnected for now
(tracked in
  `v2-refactor-temp/docs/knowledge/knowledge-todo.md`).
- Local full `pnpm lint`/`pnpm test` was not run per the project's
review
  conventions; please rely on CI / `pnpm build:check`.

### Checklist

- [x] Branch: This PR targets the correct branch — `main` for active
development, `v1` for v1 maintenance fixes
- [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.
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
NONE
```

---------

Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:04:29 +08:00
SuYao
de580c2fb1 feat(api-gateway): port the universal API gateway onto v2 (ElysiaJS rewrite) (#15705)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-07 18:04:26 +08:00
槑囿脑袋
e818c374e6 refactor(knowledge): remove sitemap source from v2 (#15682)
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-06-06 16:26:15 +08:00
fullex
bc86fb6a2e refactor(storage-monitor): move disk-space monitoring to the main process
Replace the v1 renderer-driven disk polling with a main-process service:

- Remove checkAppStorageQuota (browser storage-quota >=95% warning); v2
  business data lives in main-process SQLite, so the browser-side quota no
  longer reflects where data is stored.
- Add StorageMonitorService (WhenReady, @DependsOn WindowManager): fs.statfs
  with capacity-adaptive polling (5-60 min by free space), pushing health
  transitions (ok<->low) to the main window only.
- Rename utils/dataLimit.ts to hooks/useStorageMonitorNotification.ts, a thin
  subscriber that drives the existing antd notification (UI migration deferred
  to the broader v2 refactor).
- Drop the App_GetDiskInfo IPC handler, the getDiskInfo preload API, and the
  check-disk-space dependency.
- Add a breaking-change entry for the removed storage-quota warning.
2026-06-05 20:33:45 -07:00
SuYao
b8f1feb4f8 feat(command): introduce command system, consolidating shortcut & app-menu handling (#15699)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-05 23:24:34 +08:00
SuYao
5706307451 refactor(ai-service): consolidate AI runtime to main process (#14911)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-05 00:06:51 +08:00
Yiran
61c013bd5b feat(knowledge-base): redesign knowledge workspace (#15518)
Co-authored-by: eeee0717 <chentao020717Work@outlook.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Co-authored-by: 槑囿脑袋 <70054568+eeee0717@users.noreply.github.com>
Signed-off-by: akazaakari950718-dev <akazaakari950718@gmail.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-06-02 16:03:37 +08:00
亢奋猫
26508591f8 refactor(paintings): migrate to v2 data layer and UI (#15154)
Co-authored-by: jidan745le <420511176@qq.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: jidan745le <420511176@qq.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-02 15:18:53 +08:00
fullex
c060e867f2 docs(v2-refactor-temp): add cross-cutting v2 refactor TODO tracker
Add v2-todo.md tracking whole-refactor tasks: v1 data-stack and UI-library
teardown, migrator and schema finalization, removal-slated @deprecated sites,
and release cleanup. Link it from the directory README.
2026-05-31 19:35:46 -07:00
槑囿脑袋
2250ccb52f feat(knowledge): integrate file processing for document ingestion (#15470)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
Signed-off-by: icarus <eurfelux@gmail.com>
2026-05-31 23:10:36 +08:00
fullex
53a3577389 refactor(renderer): flatten src/renderer/src to src/renderer
Move all renderer source from src/renderer/src/* up one level to
src/renderer/*, removing the redundant nested src directory.

- Update path aliases (@renderer, @types, @logger, @data) and TanStack
  Router paths in electron.vite.config.ts; update tsconfig.{json,web,node}
  path mappings and include globs.
- Fix Vite root-relative script paths in the 8 renderer HTML entries.
- Update cross-process relative imports in main/preload (language,
  apiServer models, preload index) to drop the /src segment.
- Switch renderer test imports of the logger mock to the @test-mocks alias.
- Update hardcoded renderer paths in scripts and their fixtures, lint
  configs (eslint/oxlint/biome), CODEOWNERS, docs, and the data-classify tool.
- Convert deep (../../+) relative imports within the renderer to the
  @renderer alias (69 files, 108 imports); keep single-level relatives.
- Fix doc links broken by the move and correct one pre-existing broken
  link in naming-conventions.md.
2026-05-28 21:40:20 -07:00
fullex
c514dcc049 refactor(shared): move packages/shared to src/shared
packages/shared was never a real pnpm workspace package (no package.json); it was referenced only through the @shared TypeScript path alias. Relocate it under src/ via git mv (143 files, detected as pure renames).

Repoint the @shared alias and include globs to src/shared across electron.vite.config.ts, tsconfig.{json,node,web}.json and vitest.config.ts; update scripts/check-custom-exts.ts, scripts/update-languages.ts, the eslint.config.mjs generated-file globs, the data-classify generator output targets, .github/CODEOWNERS path rules, and CLAUDE.md/docs/source-comment references.

The @shared alias name is unchanged, so all 1403 @shared/* import sites resolve without modification. Verified with typecheck:node, typecheck:web and the full test suite (700 files, 9739 tests passing).
2026-05-28 21:02:49 -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
槑囿脑袋
9a54295c02 refactor(knowledge): knowledge workflow jobs round2 (#15371)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-05-28 20:33:18 +08:00