feat: use biome to format files (#10170)

* build: add @biomejs/biome as a dependency

* chore: add biome extension to vscode recommendations

* chore: migrate from prettier to biome for code formatting

Update VSCode settings to use Biome as the default formatter for multiple languages
Add Biome to code actions on save and reorder search exclude patterns

* build: add biome.json configuration file for code formatting

* build: migrate from prettier to biome for formatting

Update package.json scripts and biome.json configuration to use biome instead of prettier for code formatting. Adjust biome formatter includes/excludes patterns for better file matching.

* refactor(eslint): remove unused prettier config and imports

* chore: update biome.json configuration

- Enable linter and set custom rules
- Change jsxQuoteStyle to single quotes
- Add json parser configuration
- Set formatWithErrors to true

* chore: migrate biome config from json to jsonc format

The new jsonc format allows for comments in the configuration file, making it more maintainable and easier to document configuration choices.

* style(biome): update ignore patterns and jsx quote style

Update file ignore patterns from `/*` to `/**` for consistency
Change jsxQuoteStyle from single to double quotes for alignment with project standards

* refactor: simplify error type annotations from Error | any to any

The change standardizes error handling by using 'any' type instead of union types with Error | any, making the code more consistent and reducing unnecessary type complexity.

* chore: exclude tailwind.css from biome formatting

* style: standardize quote usage and fix JSX formatting

- Replace single quotes with double quotes in CSS imports and selectors
- Fix JSX element closing bracket alignment and formatting
- Standardize JSON formatting in package.json files

* Revert "style: standardize quote usage and fix JSX formatting"

This reverts commit 0947f8505d.

* fix: remove json import assertion for biome compatibility

The import assertion syntax is not supported by biome, so it was replaced with a standard import statement.

* style: change quote styles in biome.jsonc to use single quotes for JSX and double quotes for JS

* style: change quote style from double to single in biome config

* style: change JSX quote style from single to double

* chore: update biome.jsonc to use single quotes for CSS formatting

* chore: update biome config and format commands

- Exclude tailwind.css from linter includes
- Add biome lint to format commands

* style: format JSX closing brackets for better readability

* style: set bracketSameLine to true in biome config

The change aligns with common JSX formatting preferences where brackets on the same line improve readability for many developers

* Revert "style: format JSX closing brackets for better readability"

This reverts commit d442c934ee.

* style: format code and clean up whitespace

- Remove unnecessary whitespace in CSS and TS files
- Format package.json files to consistent style
- Reorder tsconfig.json properties alphabetically
- Improve code formatting in React components

* style(biome): update biome.jsonc config with clearer comment

Add explanation for keeping bracketSameLine as true to minimize changes in current PR while noting false would be better for future

* chore: remove prettier dependency and format package.json files

- Remove prettier from dependencies as it's no longer needed
- Reformat package.json files for better readability

* chore: replace prettier with biome for code formatting

Remove all prettier-related configuration, dependencies, and references
Update formatting scripts and documentation to use biome instead
Adjust electron-builder config to exclude biome.jsonc

* build: replace prettier with biome for formatting

Use biome as the default formatter instead of prettier for better performance and modern tooling support

* ci(i18n): replace prettier with biome for i18n formatting

Update the auto-i18n workflow to use Biome instead of Prettier for formatting translated files. This change simplifies the dependencies by removing multiple Prettier plugins and using a single tool for formatting.

* fix(i18n): Auto update translations for PR #10170

* style: format package.json files by consolidating array formatting

Consolidate multi-line array formatting into single-line format for better readability and consistency across package.json files

* Revert "fix(i18n): Auto update translations for PR #10170"

This reverts commit a7edd32efd.

* ci(workflows): specify biome config path in auto-i18n workflow

* chore: update biome.jsonc to use lexicographic sort order for json keys

* ci(workflows): update biome format command to use --config-path flag

* chore: exclude package.json from biome formatting

* ci: update biome.jsonc linter configuration

Update linter includes to target specific files and modify useSortedClasses rule

* chore: reorder search exclude patterns in vscode settings

* style(OGCard): reorder tailwind classes for consistent styling

* fix(biome): update tailwind classes sorting to safe and warn level

* docs(dev): update ide setup instructions in dev docs

Replace Prettier with Biome as the recommended formatter and clarify editor options

* build(extension-table-plus): replace prettier with biome for formatting

- Add biome.json configuration file
- Update package.json to use biome instead of prettier
- Remove prettier from dependencies
- Update lint script to use biome format

* chore: replace biome.json with biome.jsonc for extended configuration

Update biome configuration file to use JSONC format for comments and more detailed settings

* chore: remove unused biome.jsonc configuration file

---------

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Phantom
2025-09-15 19:21:15 +08:00
committed by GitHub
parent e3d2bb2ec6
commit e5ccf68476
24 changed files with 309 additions and 311 deletions

View File

@@ -35,7 +35,7 @@ jobs:
# 在临时目录安装依赖
mkdir -p /tmp/translation-deps
cd /tmp/translation-deps
echo '{"dependencies": {"openai": "^5.12.2", "cli-progress": "^3.12.0", "tsx": "^4.20.3", "prettier": "^3.5.3", "prettier-plugin-sort-json": "^4.1.1", "prettier-plugin-tailwindcss": "^0.6.14"}}' > package.json
echo '{"dependencies": {"openai": "^5.12.2", "cli-progress": "^3.12.0", "tsx": "^4.20.3", "@biomejs/biome": "2.2.4"}}' > package.json
npm install --no-package-lock
# 设置 NODE_PATH 让项目能找到这些依赖
@@ -45,7 +45,7 @@ jobs:
run: npx tsx scripts/auto-translate-i18n.ts
- name: 🔍 Format
run: cd /tmp/translation-deps && npx prettier --write --config /home/runner/work/cherry-studio/cherry-studio/.prettierrc /home/runner/work/cherry-studio/cherry-studio/src/renderer/src/i18n/
run: cd /tmp/translation-deps && npx biome format --config-path /home/runner/work/cherry-studio/cherry-studio/biome.jsonc --write /home/runner/work/cherry-studio/cherry-studio/src/renderer/src/i18n/
- name: 🔄 Commit changes
run: |

View File

@@ -1,14 +0,0 @@
out/
dist/
build/
.yarn/
.github/
.husky/
.vscode/
*.yaml
*.yml
*.mjs
*.cjs
*.md
*.json
src/main/integration/

View File

@@ -1,13 +0,0 @@
{
"bracketSameLine": true,
"endOfLine": "lf",
"jsonRecursiveSort": true,
"jsonSortOrder": "{\"*\": \"lexical\"}",
"plugins": ["prettier-plugin-sort-json", "prettier-plugin-tailwindcss"],
"printWidth": 120,
"semi": false,
"singleQuote": true,
"tailwindFunctions": ["clsx"],
"tailwindStylesheet": "./src/renderer/src/assets/styles/tailwind.css",
"trailingComma": "none"
}

View File

@@ -1,8 +1,8 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"editorconfig.editorconfig",
"lokalise.i18n-ally"
"lokalise.i18n-ally",
"biomejs.biome"
]
}

15
.vscode/settings.json vendored
View File

@@ -1,29 +1,30 @@
{
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"[markdown]": {
"files.trimTrailingWhitespace": false
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"source.fixAll.biome": "explicit",
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},

View File

@@ -21,7 +21,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- **Run E2E Tests**: `yarn test:e2e` - Playwright end-to-end tests
- **Type Check**: `yarn typecheck` - Checks TypeScript for both node and web
- **Lint**: `yarn lint` - ESLint with auto-fix
- **Format**: `yarn format` - Prettier formatting
- **Format**: `yarn format` - Biome formatting
### Build & Release

97
biome.jsonc Normal file
View File

@@ -0,0 +1,97 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"assist": {
// to sort json
"actions": {
"source": {
"organizeImports": "on",
"useSortedKeys": {
"level": "on",
"options": {
"sortOrder": "lexicographic"
}
}
}
},
"enabled": true,
"includes": ["**/*.json", "!*.json", "!**/package.json"]
},
"css": {
"formatter": {
"quoteStyle": "single"
}
},
"files": { "ignoreUnknown": false },
"formatter": {
"attributePosition": "auto",
"bracketSameLine": false,
"bracketSpacing": true,
"enabled": true,
"expand": "auto",
"formatWithErrors": true,
"includes": [
"**",
"!out/**",
"!**/dist/**",
"!build/**",
"!.yarn/**",
"!.github/**",
"!.husky/**",
"!.vscode/**",
"!*.yaml",
"!*.yml",
"!*.mjs",
"!*.cjs",
"!*.md",
"!*.json",
"!src/main/integration/**",
"!**/tailwind.css",
"!**/package.json"
],
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 120,
"useEditorconfig": true
},
"html": { "formatter": { "selfCloseVoidElements": "always" } },
"javascript": {
"formatter": {
"arrowParentheses": "always",
"attributePosition": "auto",
// To minimize changes in this PR as much as possible, it's set to true. However, setting it to false would make it more convenient to add attributes at the end.
"bracketSameLine": true,
"bracketSpacing": true,
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"quoteStyle": "single",
"semicolons": "asNeeded",
"trailingCommas": "none"
}
},
"json": {
"parser": {
"allowComments": true
}
},
"linter": {
"enabled": true,
"includes": ["!**/tailwind.css", "src/renderer/**/*.{tsx,ts}"],
// only enable sorted tailwind css rule. used as formatter instead of linter
"rules": {
"nursery": {
// to sort tailwind css classes
"useSortedClasses": {
"fix": "safe",
"level": "warn",
"options": {
"functions": ["cn"]
}
}
},
"recommended": false,
"suspicious": "off"
}
},
"vcs": { "clientKind": "git", "enabled": false, "useIgnoreFile": false }
}

View File

@@ -2,7 +2,9 @@
## IDE Setup
[Cursor](https://www.cursor.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
- Editor: [Cursor](https://www.cursor.com/), etc. Any VS Code compatible editor.
- Linter: [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- Formatter: [Biome](https://marketplace.visualstudio.com/items?itemName=biomejs.biome)
## Project Setup

View File

@@ -17,52 +17,52 @@ protocols:
schemes:
- cherrystudio
files:
- '**/*'
- '!**/{.vscode,.yarn,.yarn-lock,.github,.cursorrules,.prettierrc}'
- '!electron.vite.config.{js,ts,mjs,cjs}}'
- '!**/{.eslintignore,.eslintrc.js,.eslintrc.json,.eslintcache,root.eslint.config.js,eslint.config.js,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,eslint.config.mjs,dev-app-update.yml,CHANGELOG.md,README.md}'
- '!**/{.env,.env.*,.npmrc,pnpm-lock.yaml}'
- '!**/{tsconfig.json,tsconfig.tsbuildinfo,tsconfig.node.json,tsconfig.web.json}'
- '!**/{.editorconfig,.jekyll-metadata}'
- '!src'
- '!scripts'
- '!local'
- '!docs'
- '!packages'
- '!.swc'
- '!.bin'
- '!._*'
- '!*.log'
- '!stats.html'
- '!*.md'
- '!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}'
- '!**/*.{map,ts,tsx,jsx,less,scss,sass,css.d.ts,d.cts,d.mts,md,markdown,yaml,yml}'
- '!**/{test,tests,__tests__,powered-test,coverage}/**'
- '!**/{example,examples}/**'
- '!**/*.{spec,test}.{js,jsx,ts,tsx}'
- '!**/*.min.*.map'
- '!**/*.d.ts'
- '!**/dist/es6/**'
- '!**/dist/demo/**'
- '!**/amd/**'
- '!**/{.DS_Store,Thumbs.db,thumbs.db,__pycache__}'
- '!**/{LICENSE,license,LICENSE.*,*.LICENSE.txt,NOTICE.txt,README.md,readme.md,CHANGELOG.md}'
- '!node_modules/rollup-plugin-visualizer'
- '!node_modules/js-tiktoken'
- '!node_modules/@tavily/core/node_modules/js-tiktoken'
- '!node_modules/pdf-parse/lib/pdf.js/{v1.9.426,v1.10.88,v2.0.550}'
- '!node_modules/mammoth/{mammoth.browser.js,mammoth.browser.min.js}'
- '!node_modules/selection-hook/prebuilds/**/*' # we rebuild .node, don't use prebuilds
- '!node_modules/selection-hook/node_modules' # we don't need what in the node_modules dir
- '!node_modules/selection-hook/src' # we don't need source files
- '!node_modules/tesseract.js-core/{tesseract-core.js,tesseract-core.wasm,tesseract-core.wasm.js}' # we don't need source files
- '!node_modules/tesseract.js-core/{tesseract-core-lstm.js,tesseract-core-lstm.wasm,tesseract-core-lstm.wasm.js}' # we don't need source files
- '!node_modules/tesseract.js-core/{tesseract-core-simd-lstm.js,tesseract-core-simd-lstm.wasm,tesseract-core-simd-lstm.wasm.js}' # we don't need source files
- '!**/*.{h,iobj,ipdb,tlog,recipe,vcxproj,vcxproj.filters,Makefile,*.Makefile}' # filter .node build files
- "**/*"
- "!**/{.vscode,.yarn,.yarn-lock,.github,.cursorrules,.prettierrc}"
- "!electron.vite.config.{js,ts,mjs,cjs}}"
- "!**/{.eslintignore,.eslintrc.js,.eslintrc.json,.eslintcache,root.eslint.config.js,eslint.config.js,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,eslint.config.mjs,dev-app-update.yml,CHANGELOG.md,README.md,biome.jsonc}"
- "!**/{.env,.env.*,.npmrc,pnpm-lock.yaml}"
- "!**/{tsconfig.json,tsconfig.tsbuildinfo,tsconfig.node.json,tsconfig.web.json}"
- "!**/{.editorconfig,.jekyll-metadata}"
- "!src"
- "!scripts"
- "!local"
- "!docs"
- "!packages"
- "!.swc"
- "!.bin"
- "!._*"
- "!*.log"
- "!stats.html"
- "!*.md"
- "!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}"
- "!**/*.{map,ts,tsx,jsx,less,scss,sass,css.d.ts,d.cts,d.mts,md,markdown,yaml,yml}"
- "!**/{test,tests,__tests__,powered-test,coverage}/**"
- "!**/{example,examples}/**"
- "!**/*.{spec,test}.{js,jsx,ts,tsx}"
- "!**/*.min.*.map"
- "!**/*.d.ts"
- "!**/dist/es6/**"
- "!**/dist/demo/**"
- "!**/amd/**"
- "!**/{.DS_Store,Thumbs.db,thumbs.db,__pycache__}"
- "!**/{LICENSE,license,LICENSE.*,*.LICENSE.txt,NOTICE.txt,README.md,readme.md,CHANGELOG.md}"
- "!node_modules/rollup-plugin-visualizer"
- "!node_modules/js-tiktoken"
- "!node_modules/@tavily/core/node_modules/js-tiktoken"
- "!node_modules/pdf-parse/lib/pdf.js/{v1.9.426,v1.10.88,v2.0.550}"
- "!node_modules/mammoth/{mammoth.browser.js,mammoth.browser.min.js}"
- "!node_modules/selection-hook/prebuilds/**/*" # we rebuild .node, don't use prebuilds
- "!node_modules/selection-hook/node_modules" # we don't need what in the node_modules dir
- "!node_modules/selection-hook/src" # we don't need source files
- "!node_modules/tesseract.js-core/{tesseract-core.js,tesseract-core.wasm,tesseract-core.wasm.js}" # we don't need source files
- "!node_modules/tesseract.js-core/{tesseract-core-lstm.js,tesseract-core-lstm.wasm,tesseract-core-lstm.wasm.js}" # we don't need source files
- "!node_modules/tesseract.js-core/{tesseract-core-simd-lstm.js,tesseract-core-simd-lstm.wasm,tesseract-core-simd-lstm.wasm.js}" # we don't need source files
- "!**/*.{h,iobj,ipdb,tlog,recipe,vcxproj,vcxproj.filters,Makefile,*.Makefile}" # filter .node build files
asarUnpack:
- resources/**
- '**/*.{metal,exp,lib}'
- 'node_modules/@img/sharp-libvips-*/**'
- "**/*.{metal,exp,lib}"
- "node_modules/@img/sharp-libvips-*/**"
win:
executableName: Cherry Studio
artifactName: ${productName}-${version}-${arch}-setup.${ext}
@@ -88,7 +88,7 @@ mac:
entitlementsInherit: build/entitlements.mac.plist
notarize: false
artifactName: ${productName}-${version}-${arch}.${ext}
minimumSystemVersion: '20.1.0' # 最低支持 macOS 11.0
minimumSystemVersion: "20.1.0" # 最低支持 macOS 11.0
extendInfo:
- NSCameraUsageDescription: Application requests access to the device's camera.
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
@@ -113,7 +113,7 @@ linux:
rpm:
# Workaround for electron build issue on rpm package:
# https://github.com/electron/forge/issues/3594
fpm: ['--rpm-rpmbuild-define=_build_id_links none']
fpm: ["--rpm-rpmbuild-define=_build_id_links none"]
publish:
provider: generic
url: https://releases.cherry-ai.com

View File

@@ -4,7 +4,9 @@ import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import { resolve } from 'path'
import { visualizer } from 'rollup-plugin-visualizer'
import pkg from './package.json' assert { type: 'json' }
// assert not supported by biome
// import pkg from './package.json' assert { type: 'json' }
import pkg from './package.json'
const visualizerPlugin = (type: 'renderer' | 'main') => {
return process.env[`VISUALIZER_${type.toUpperCase()}`] ? [visualizer({ open: true })] : []

View File

@@ -1,4 +1,3 @@
import electronConfigPrettier from '@electron-toolkit/eslint-config-prettier'
import tseslint from '@electron-toolkit/eslint-config-ts'
import eslint from '@eslint/js'
import eslintReact from '@eslint-react/eslint-plugin'
@@ -10,7 +9,6 @@ import unusedImports from 'eslint-plugin-unused-imports'
export default defineConfig([
eslint.configs.recommended,
tseslint.configs.recommended,
electronConfigPrettier,
eslintReact.configs['recommended-typescript'],
reactHooks.configs['recommended-latest'],
{
@@ -26,7 +24,6 @@ export default defineConfig([
'simple-import-sort/exports': 'error',
'unused-imports/no-unused-imports': 'error',
'@eslint-react/no-prop-types': 'error',
'prettier/prettier': ['error']
}
},
// Configuration for ensuring compatibility with the original ESLint(8.x) rules

View File

@@ -65,8 +65,8 @@
"test:e2e": "yarn playwright test",
"test:lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts",
"test:scripts": "vitest scripts",
"format": "prettier --write .",
"format:check": "prettier --check .",
"format": "biome format --write && biome lint --write",
"format:check": "biome format && biome lint",
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix && yarn typecheck && yarn check:i18n",
"prepare": "git config blame.ignoreRevsFile .git-blame-ignore-revs && husky",
"claude": "dotenv -e .env -- claude"
@@ -104,6 +104,7 @@
"@aws-sdk/client-bedrock": "^3.840.0",
"@aws-sdk/client-bedrock-runtime": "^3.840.0",
"@aws-sdk/client-s3": "^3.840.0",
"@biomejs/biome": "2.2.4",
"@cherrystudio/ai-core": "workspace:*",
"@cherrystudio/embedjs": "^0.1.31",
"@cherrystudio/embedjs-libsql": "^0.1.31",
@@ -122,7 +123,6 @@
"@dnd-kit/modifiers": "^9.0.0",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@electron-toolkit/eslint-config-prettier": "^3.0.0",
"@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/preload": "^3.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
@@ -284,9 +284,6 @@
"pdf-lib": "^1.17.1",
"pdf-parse": "^1.1.1",
"playwright": "^1.52.0",
"prettier": "^3.5.3",
"prettier-plugin-sort-json": "^4.1.1",
"prettier-plugin-tailwindcss": "^0.6.14",
"proxy-agent": "^6.5.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@@ -369,11 +366,11 @@
"packageManager": "yarn@4.9.1",
"lint-staged": {
"*.{js,jsx,ts,tsx,cjs,mjs,cts,mts}": [
"prettier --write",
"biome format --write",
"eslint --fix"
],
"*.{json,yml,yaml,css,html}": [
"prettier --write"
"biome format --write"
]
}
}

View File

@@ -13,15 +13,7 @@
"test": "vitest run",
"test:watch": "vitest"
},
"keywords": [
"ai",
"sdk",
"openai",
"anthropic",
"google",
"cherry-studio",
"vercel-ai-sdk"
],
"keywords": ["ai", "sdk", "openai", "anthropic", "google", "cherry-studio", "vercel-ai-sdk"],
"author": "Cherry Studio",
"license": "MIT",
"repository": {
@@ -56,9 +48,7 @@
"engines": {
"node": ">=18.0.0"
},
"files": [
"dist"
],
"files": ["dist"],
"exports": {
".": {
"types": "./dist/index.d.ts",

View File

@@ -24,7 +24,6 @@ export const googleToolsPlugin = (config?: ToolConfig) =>
if (!typedParams.tools) {
typedParams.tools = {}
}
// 使用类型安全的方式遍历配置
;(Object.keys(config) as ToolConfigKey[]).forEach((key) => {
if (config[key] && key in toolNameMap && key in google.tools) {

View File

@@ -1,26 +1,21 @@
{
"compilerOptions": {
"target": "ES2020",
"allowSyntheticDefaultImports": true,
"declaration": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"noEmitOnError": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
"outDir": "./dist",
"resolveJsonModule": true,
"rootDir": "./src",
"skipLibCheck": true,
"strict": true,
"target": "ES2020"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist"
]
}
"exclude": ["node_modules", "dist"],
"include": ["src/**/*"]
}

View File

@@ -67,13 +67,13 @@
"dist"
],
"devDependencies": {
"@biomejs/biome": "2.2.4",
"@tiptap/core": "^3.2.0",
"@tiptap/pm": "^3.2.0",
"eslint": "^9.22.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unused-imports": "^4.1.4",
"prettier": "^3.5.3",
"tsdown": "^0.13.3"
},
"peerDependencies": {
@@ -87,7 +87,7 @@
},
"scripts": {
"build": "tsdown",
"lint": "prettier ./src/ --write && eslint --fix ./src/"
"lint": "biome format ./src/ --write && eslint --fix ./src/"
},
"packageManager": "yarn@4.9.1"
}

View File

@@ -75,17 +75,17 @@ export const languages: Record<string, LanguageData> = ${languagesObjectString};
}
/**
* Formats a file using Prettier.
* Formats a file using Biome.
* @param filePath The path to the file to format.
*/
async function formatWithPrettier(filePath: string): Promise<void> {
console.log('🎨 Formatting file with Prettier...')
async function format(filePath: string): Promise<void> {
console.log('🎨 Formatting file with Biome...')
try {
await execAsync(`yarn prettier --write ${filePath}`)
console.log('✅ Prettier formatting complete.')
await execAsync(`yarn biome format --write ${filePath}`)
console.log('✅ Biome formatting complete.')
} catch (e: any) {
console.error('❌ Prettier formatting failed:', e.stdout || e.stderr)
throw new Error('Prettier formatting failed.')
console.error('❌ Biome formatting failed:', e.stdout || e.stderr)
throw new Error('Biome formatting failed.')
}
}
@@ -116,7 +116,7 @@ async function updateLanguagesFile(): Promise<void> {
await fs.writeFile(LANGUAGES_FILE_PATH, fileContent, 'utf-8')
console.log(`✅ Successfully wrote to ${LANGUAGES_FILE_PATH}`)
await formatWithPrettier(LANGUAGES_FILE_PATH)
await format(LANGUAGES_FILE_PATH)
await checkTypeScript(LANGUAGES_FILE_PATH)
console.log('🎉 Successfully updated languages.ts file!')

View File

@@ -235,7 +235,7 @@ class McpService {
try {
await inMemoryServer.connect(serverTransport)
getServerLogger(server).debug(`In-memory server started`)
} catch (error: Error | any) {
} catch (error: any) {
getServerLogger(server).error(`Error starting in-memory server`, error as Error)
throw new Error(`Failed to start in-memory server: ${error.message}`)
}
@@ -419,7 +419,7 @@ class McpService {
const transport = await initTransport()
try {
await client.connect(transport)
} catch (error: Error | any) {
} catch (error: any) {
if (
error instanceof Error &&
(error.name === 'UnauthorizedError' || error.message.includes('Unauthorized'))
@@ -852,7 +852,7 @@ class McpService {
return {
contents: contents
}
} catch (error: Error | any) {
} catch (error: any) {
getServerLogger(server, { uri }).error(`Failed to get resource`, error as Error)
throw new Error(`Failed to get resource ${uri} from server: ${server.name}: ${error.message}`)
}

View File

@@ -1,6 +1,5 @@
.command-list-popover {
/* Base styles are handled inline for theme support */
/* Arrow styles based on placement */
}

View File

@@ -36,7 +36,7 @@ export const OGCard = ({ link, show }: Props) => {
const GeneratedGraph = useCallback(() => {
return (
<div className="flex h-36 items-center justify-center bg-accent p-4">
<h2 className="text-2xl font-bold">{metadata['og:title'] || hostname}</h2>
<h2 className="font-bold text-2xl">{metadata['og:title'] || hostname}</h2>
</div>
)
}, [hostname, metadata])

View File

@@ -318,7 +318,7 @@ const MCPToolsButton: FC<Props> = ({ ref, setInputValue, resizeTextArea, Toolbar
})
await handlePromptResponse(response)
} catch (error: Error | any) {
} catch (error: any) {
if (error.message !== 'cancelled') {
window.modal.error({
title: t('common.error'),
@@ -335,7 +335,7 @@ const MCPToolsButton: FC<Props> = ({ ref, setInputValue, resizeTextArea, Toolbar
name: prompt.name
})
await handlePromptResponse(response)
} catch (error: Error | any) {
} catch (error: any) {
window.modal.error({
title: t('common.error'),
content: error.message || t('settings.mcp.prompts.genericError')
@@ -416,7 +416,7 @@ const MCPToolsButton: FC<Props> = ({ ref, setInputValue, resizeTextArea, Toolbar
} else {
processResourceContent(response as ResourceData)
}
} catch (error: Error | any) {
} catch (error: any) {
window.modal.error({
title: t('common.error'),
content: error.message || t('settings.mcp.resources.genericError')

View File

@@ -15,7 +15,9 @@ const MessageContent: React.FC<Props> = ({ message }) => {
<>
{!isEmpty(message.mentions) && (
<Flex gap="8px" wrap style={{ marginBottom: '10px' }}>
{message.mentions?.map((model) => <MentionTag key={getModelUniqId(model)}>{'@' + model.name}</MentionTag>)}
{message.mentions?.map((model) => (
<MentionTag key={getModelUniqId(model)}>{'@' + model.name}</MentionTag>
))}
</Flex>
)}
<MessageBlockRenderer blocks={message.blocks} message={message} />

View File

@@ -141,7 +141,11 @@ export async function backupToWebdav({
showMessage = false,
customFileName = '',
autoBackupProcess = false
}: { showMessage?: boolean; customFileName?: string; autoBackupProcess?: boolean } = {}) {
}: {
showMessage?: boolean
customFileName?: string
autoBackupProcess?: boolean
} = {}) {
const notificationService = NotificationService.getInstance()
if (isManualBackupRunning) {
logger.verbose('Manual backup already in progress')
@@ -319,7 +323,11 @@ export async function backupToS3({
showMessage = false,
customFileName = '',
autoBackupProcess = false
}: { showMessage?: boolean; customFileName?: string; autoBackupProcess?: boolean } = {}) {
}: {
showMessage?: boolean
customFileName?: string
autoBackupProcess?: boolean
} = {}) {
const notificationService = NotificationService.getInstance()
if (isManualBackupRunning) {
logger.verbose('Manual backup already in progress')

254
yarn.lock
View File

@@ -2249,6 +2249,97 @@ __metadata:
languageName: node
linkType: hard
"@biomejs/biome@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/biome@npm:2.2.4"
dependencies:
"@biomejs/cli-darwin-arm64": "npm:2.2.4"
"@biomejs/cli-darwin-x64": "npm:2.2.4"
"@biomejs/cli-linux-arm64": "npm:2.2.4"
"@biomejs/cli-linux-arm64-musl": "npm:2.2.4"
"@biomejs/cli-linux-x64": "npm:2.2.4"
"@biomejs/cli-linux-x64-musl": "npm:2.2.4"
"@biomejs/cli-win32-arm64": "npm:2.2.4"
"@biomejs/cli-win32-x64": "npm:2.2.4"
dependenciesMeta:
"@biomejs/cli-darwin-arm64":
optional: true
"@biomejs/cli-darwin-x64":
optional: true
"@biomejs/cli-linux-arm64":
optional: true
"@biomejs/cli-linux-arm64-musl":
optional: true
"@biomejs/cli-linux-x64":
optional: true
"@biomejs/cli-linux-x64-musl":
optional: true
"@biomejs/cli-win32-arm64":
optional: true
"@biomejs/cli-win32-x64":
optional: true
bin:
biome: bin/biome
checksum: 10c0/7229fcc743db48f3cfd7417fb3f33d1cd9e7dfe42a12ed3c1046cd3110718237bb71ea3fe5c8b0de9bd3df2b918d0be58027602aa3720b64904b63d9cedf53e3
languageName: node
linkType: hard
"@biomejs/cli-darwin-arm64@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-darwin-arm64@npm:2.2.4"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@biomejs/cli-darwin-x64@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-darwin-x64@npm:2.2.4"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@biomejs/cli-linux-arm64-musl@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-linux-arm64-musl@npm:2.2.4"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@biomejs/cli-linux-arm64@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-linux-arm64@npm:2.2.4"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@biomejs/cli-linux-x64-musl@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-linux-x64-musl@npm:2.2.4"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@biomejs/cli-linux-x64@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-linux-x64@npm:2.2.4"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@biomejs/cli-win32-arm64@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-win32-arm64@npm:2.2.4"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@biomejs/cli-win32-x64@npm:2.2.4":
version: 2.2.4
resolution: "@biomejs/cli-win32-x64@npm:2.2.4"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@braintree/sanitize-url@npm:^7.0.4":
version: 7.1.1
resolution: "@braintree/sanitize-url@npm:7.1.1"
@@ -2511,13 +2602,13 @@ __metadata:
version: 0.0.0-use.local
resolution: "@cherrystudio/extension-table-plus@workspace:packages/extension-table-plus"
dependencies:
"@biomejs/biome": "npm:2.2.4"
"@tiptap/core": "npm:^3.2.0"
"@tiptap/pm": "npm:^3.2.0"
eslint: "npm:^9.22.0"
eslint-plugin-react-hooks: "npm:^5.2.0"
eslint-plugin-simple-import-sort: "npm:^12.1.1"
eslint-plugin-unused-imports: "npm:^4.1.4"
prettier: "npm:^3.5.3"
tsdown: "npm:^0.13.3"
peerDependencies:
"@tiptap/core": ^3.0.9
@@ -3099,19 +3190,6 @@ __metadata:
languageName: node
linkType: hard
"@electron-toolkit/eslint-config-prettier@npm:^3.0.0":
version: 3.0.0
resolution: "@electron-toolkit/eslint-config-prettier@npm:3.0.0"
dependencies:
eslint-config-prettier: "npm:^10.0.1"
eslint-plugin-prettier: "npm:^5.2.3"
peerDependencies:
eslint: ">= 9.0.0"
prettier: ">= 3.0.0"
checksum: 10c0/c17e272c83b9bcc0ce87b7d116b0eb2606920202c342f65332e0d792f89322de5382b8a345a79d291e45a21d5159eb82fc4e8ec8efbff2f535e336502bb8a998
languageName: node
linkType: hard
"@electron-toolkit/eslint-config-ts@npm:^3.0.0":
version: 3.1.0
resolution: "@electron-toolkit/eslint-config-ts@npm:3.1.0"
@@ -7172,13 +7250,6 @@ __metadata:
languageName: node
linkType: hard
"@pkgr/core@npm:^0.2.3":
version: 0.2.4
resolution: "@pkgr/core@npm:0.2.4"
checksum: 10c0/2528a443bbbef5d4686614e1d73f834f19ccbc975f62b2a64974a6b97bcdf677b9c5e8948e04808ac4f0d853e2f422adfaae2a06e9e9f4f5cf8af76f1adf8dc1
languageName: node
linkType: hard
"@playwright/test@npm:^1.52.0":
version: 1.52.0
resolution: "@playwright/test@npm:1.52.0"
@@ -13008,6 +13079,7 @@ __metadata:
"@aws-sdk/client-bedrock": "npm:^3.840.0"
"@aws-sdk/client-bedrock-runtime": "npm:^3.840.0"
"@aws-sdk/client-s3": "npm:^3.840.0"
"@biomejs/biome": "npm:2.2.4"
"@cherrystudio/ai-core": "workspace:*"
"@cherrystudio/embedjs": "npm:^0.1.31"
"@cherrystudio/embedjs-libsql": "npm:^0.1.31"
@@ -13026,7 +13098,6 @@ __metadata:
"@dnd-kit/modifiers": "npm:^9.0.0"
"@dnd-kit/sortable": "npm:^10.0.0"
"@dnd-kit/utilities": "npm:^3.2.2"
"@electron-toolkit/eslint-config-prettier": "npm:^3.0.0"
"@electron-toolkit/eslint-config-ts": "npm:^3.0.0"
"@electron-toolkit/preload": "npm:^3.0.0"
"@electron-toolkit/tsconfig": "npm:^1.0.1"
@@ -13199,9 +13270,6 @@ __metadata:
pdf-lib: "npm:^1.17.1"
pdf-parse: "npm:^1.1.1"
playwright: "npm:^1.52.0"
prettier: "npm:^3.5.3"
prettier-plugin-sort-json: "npm:^4.1.1"
prettier-plugin-tailwindcss: "npm:^0.6.14"
proxy-agent: "npm:^6.5.0"
react: "npm:^19.0.0"
react-dom: "npm:^19.0.0"
@@ -16978,37 +17046,6 @@ __metadata:
languageName: node
linkType: hard
"eslint-config-prettier@npm:^10.0.1":
version: 10.1.2
resolution: "eslint-config-prettier@npm:10.1.2"
peerDependencies:
eslint: ">=7.0.0"
bin:
eslint-config-prettier: bin/cli.js
checksum: 10c0/c22c8e29193cc8fd70becf1c2dd072513f2b3004a175c2a49404c79d1745ba4dc0edc2afd00d16b0e26d24f95813a0469e7445a25104aec218f6d84cdb1697e9
languageName: node
linkType: hard
"eslint-plugin-prettier@npm:^5.2.3":
version: 5.2.6
resolution: "eslint-plugin-prettier@npm:5.2.6"
dependencies:
prettier-linter-helpers: "npm:^1.0.0"
synckit: "npm:^0.11.0"
peerDependencies:
"@types/eslint": ">=8.0.0"
eslint: ">=8.0.0"
eslint-config-prettier: ">= 7.0.0 <10.0.0 || >=10.1.0"
prettier: ">=3.0.0"
peerDependenciesMeta:
"@types/eslint":
optional: true
eslint-config-prettier:
optional: true
checksum: 10c0/9911740a5edac7933d92671381908671c61ffa32a3cee7aed667ebab89831ee2c0b69eb9530f68dbe172ca9d4b3fa3d47350762dc1eb096a3ce125fa31c0e616
languageName: node
linkType: hard
"eslint-plugin-react-debug@npm:1.48.1":
version: 1.48.1
resolution: "eslint-plugin-react-debug@npm:1.48.1"
@@ -17585,7 +17622,7 @@ __metadata:
languageName: node
linkType: hard
"fast-diff@npm:^1.1.2, fast-diff@npm:^1.3.0":
"fast-diff@npm:^1.3.0":
version: 1.3.0
resolution: "fast-diff@npm:1.3.0"
checksum: 10c0/5c19af237edb5d5effda008c891a18a585f74bf12953be57923f17a3a4d0979565fc64dbc73b9e20926b9d895f5b690c618cbb969af0cf022e3222471220ad29
@@ -23608,97 +23645,6 @@ __metadata:
languageName: node
linkType: hard
"prettier-linter-helpers@npm:^1.0.0":
version: 1.0.0
resolution: "prettier-linter-helpers@npm:1.0.0"
dependencies:
fast-diff: "npm:^1.1.2"
checksum: 10c0/81e0027d731b7b3697ccd2129470ed9913ecb111e4ec175a12f0fcfab0096516373bf0af2fef132af50cafb0a905b74ff57996d615f59512bb9ac7378fcc64ab
languageName: node
linkType: hard
"prettier-plugin-sort-json@npm:^4.1.1":
version: 4.1.1
resolution: "prettier-plugin-sort-json@npm:4.1.1"
peerDependencies:
prettier: ^3.0.0
checksum: 10c0/b3b86ea679e95d0329c367aa860af4033d8a3b83a0656d7393f2005b2df78e20d19fbe2c40fe7b531262210e40060318a4287459c2a4f61c6a6bd1c2757e2b7d
languageName: node
linkType: hard
"prettier-plugin-tailwindcss@npm:^0.6.14":
version: 0.6.14
resolution: "prettier-plugin-tailwindcss@npm:0.6.14"
peerDependencies:
"@ianvs/prettier-plugin-sort-imports": "*"
"@prettier/plugin-hermes": "*"
"@prettier/plugin-oxc": "*"
"@prettier/plugin-pug": "*"
"@shopify/prettier-plugin-liquid": "*"
"@trivago/prettier-plugin-sort-imports": "*"
"@zackad/prettier-plugin-twig": "*"
prettier: ^3.0
prettier-plugin-astro: "*"
prettier-plugin-css-order: "*"
prettier-plugin-import-sort: "*"
prettier-plugin-jsdoc: "*"
prettier-plugin-marko: "*"
prettier-plugin-multiline-arrays: "*"
prettier-plugin-organize-attributes: "*"
prettier-plugin-organize-imports: "*"
prettier-plugin-sort-imports: "*"
prettier-plugin-style-order: "*"
prettier-plugin-svelte: "*"
peerDependenciesMeta:
"@ianvs/prettier-plugin-sort-imports":
optional: true
"@prettier/plugin-hermes":
optional: true
"@prettier/plugin-oxc":
optional: true
"@prettier/plugin-pug":
optional: true
"@shopify/prettier-plugin-liquid":
optional: true
"@trivago/prettier-plugin-sort-imports":
optional: true
"@zackad/prettier-plugin-twig":
optional: true
prettier-plugin-astro:
optional: true
prettier-plugin-css-order:
optional: true
prettier-plugin-import-sort:
optional: true
prettier-plugin-jsdoc:
optional: true
prettier-plugin-marko:
optional: true
prettier-plugin-multiline-arrays:
optional: true
prettier-plugin-organize-attributes:
optional: true
prettier-plugin-organize-imports:
optional: true
prettier-plugin-sort-imports:
optional: true
prettier-plugin-style-order:
optional: true
prettier-plugin-svelte:
optional: true
checksum: 10c0/1bf635be28b30b3f171a184497eecf512601d19328e402dd2eb1ede52aa57b4f5b605eae2929f4916de9ba22526f3d730d9afa90334db09d17c59f463f7b26d8
languageName: node
linkType: hard
"prettier@npm:^3.5.3":
version: 3.5.3
resolution: "prettier@npm:3.5.3"
bin:
prettier: bin/prettier.cjs
checksum: 10c0/3880cb90b9dc0635819ab52ff571518c35bd7f15a6e80a2054c05dbc8a3aa6e74f135519e91197de63705bcb38388ded7e7230e2178432a1468005406238b877
languageName: node
linkType: hard
"pretty-format@npm:^27.0.2":
version: 27.5.1
resolution: "pretty-format@npm:27.5.1"
@@ -26857,16 +26803,6 @@ __metadata:
languageName: node
linkType: hard
"synckit@npm:^0.11.0":
version: 0.11.4
resolution: "synckit@npm:0.11.4"
dependencies:
"@pkgr/core": "npm:^0.2.3"
tslib: "npm:^2.8.1"
checksum: 10c0/dd2965a37c93c0b652bf07b1fd8d1639a803b65cf34c0cb1b827b8403044fc3b09ec87f681d922a324825127ee95b2e0394e7caccb502f407892d63e903c5276
languageName: node
linkType: hard
"tailwind-merge@npm:3.3.1":
version: 3.3.1
resolution: "tailwind-merge@npm:3.3.1"
@@ -27509,7 +27445,7 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0, tslib@npm:^2.8.1":
"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62