Compare commits

..

171 Commits

Author SHA1 Message Date
suyao
8ddf53d2d2 feat(textarea): remove TextareaContext and update stories to reflect new error handling 2025-12-01 20:28:46 +08:00
suyao
3c89146458 feat(textarea): refactor TextareaInput to simplify props and remove autoSize handling 2025-12-01 20:10:57 +08:00
suyao
4386802746 fix: format 2025-11-14 18:47:33 +08:00
suyao
643aed66ca feat(textarea): add TextareaContext for managing textarea state 2025-11-14 18:45:05 +08:00
suyao
6d1675380f feat(textarea): refactor Textarea stories to use custom label and caption components 2025-11-14 18:40:14 +08:00
suyao
0371daa076 fix ci 2025-11-14 17:17:03 +08:00
suyao
c43633e165 Fine-tuning the style 2025-11-14 17:05:02 +08:00
suyao
70660b1181 feat(textarea): enhance Textarea component with context, improved variants, and Storybook examples 2025-11-14 17:05:01 +08:00
suyao
e0dba6cad1 feat(textarea): add Textarea component with variants and Storybook examples 2025-11-14 17:05:00 +08:00
MyPrototypeWhat
a3062d6e38 Add ICON_IMPLEMENTATION_GUIDE and new SVG icons
- Created ICON_IMPLEMENTATION_GUIDE.md to document icon usage and common issues.
- Added multiple new SVG icons to the `icons/` directory, enhancing the icon library.
- Updated tailwind.css for improved styling consistency across components.
2025-11-14 13:31:17 +08:00
MyPrototypeWhat
43fb232cca Update tailwind.css to use glob pattern for component imports 2025-11-13 17:28:02 +08:00
SuYao
d610943f0f Fix/merge-main (#11262)
* merge branch 'main'

* fix: lint error

* fix yarn lock

* fix: lock

* fix: ci

* fix: yarn lock
2025-11-12 22:49:58 +08:00
fullex
680fcb4b9d Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-12 20:41:05 +08:00
SuYao
a6182eaf85 Refactor/inputbar (#10332)
* Refactor inputbar system with configurable scope-based architecture

- **Implement scope-based configuration** for chat, agent sessions, and mini-window with feature toggles
- **Add tool registry system** with dependency injection for modular inputbar tools
- **Create shared state management** via InputbarToolsProvider for consistent state handling
- **Migrate existing tools** to registry-based definitions with proper scope filtering

The changes introduce a flexible inputbar architecture that supports different use cases through scope-based configuration while maintaining feature parity and improving code organization.

* Remove unused import and refactor tool rendering

- Delete obsolete '@renderer/pages/home/Inputbar/tools' import from Inputbar.tsx
- Extract ToolButton component to render tools outside useMemo dependency cycle
- Store tool definitions in config for deferred rendering with current context
- Fix potential stale closure issues in tool rendering by rebuilding context on each render

* Wrap ToolButton in React.memo and optimize quick panel menu updates

- Memoize ToolButton component to prevent unnecessary re-renders when tool key remains unchanged
- Replace direct menu state updates with version-based triggering to batch registry changes
- Add useEffect to consolidate menu updates and reduce redundant flat operations

* chore style

* refactor(InputbarToolsProvider): simplify quick panel menu update logic

* Improve QuickPanel behavior and input handling

- Default select first item when panel symbol changes to enhance user experience
- Add Tab key support for selecting template variables in input field
- Refactor QuickPanel trigger logic with better symbol tracking and boundary checks
- Fix typo in translation key for model selection menu item

* Refactor import statements to use type-only imports

- Convert inline type imports to explicit type imports in Inputbar.tsx and types.ts
- Replace combined type/value imports with separate type imports in InputbarToolsProvider and tools
- Remove unnecessary menu version state and effect in InputbarToolsProvider

* Refactor InputbarTools context to separate state and dispatch concerns

- Split single context into separate state and dispatch contexts to optimize re-renders
- Introduce derived state for `couldMentionNotVisionModel` based on file types
- Encapsulate Quick Panel API in stable object with memoized functions
- Add internal dispatch context for Inputbar-specific state setters

* Refactor Inputbar to use split context hooks and optimize QuickPanel

- Replace monolithic `useInputbarTools` with separate state, dispatch, and internal dispatch hooks
- Move text state from context to local component state in InputbarInner
- Optimize QuickPanel trigger registration to use ref pattern, avoiding frequent re-registrations

* Refactor QuickPanel API to separate concerns between tools and inputbar

- Split QuickPanel API into `toolsRegistry` for tool registration and `triggers` for inputbar triggering
- Remove unused QuickPanel state variables and clean up dependencies
- Update tool context to use new API structure with proper type safety

* Optimize the state management of QuickPanel and Inputbar, add text update functionality, and improve the tool registration logic.

* chore

* Add reusable React hooks and InputbarCore component for chat input

- Create `useInputText`, `useKeyboardHandler`, and `useTextareaResize` hooks for text management, keyboard shortcuts, and auto-resizing
- Implement `InputbarCore` component with modular toolbar sections, drag-drop support, and textarea customization
- Add `useFileDragDrop` and `usePasteHandler` hooks for file uploads and paste handling with type filtering

* Refactor Inputbar to use custom hooks for text and textarea management

- Replace manual text state with useInputText hook for text management and empty state
- Replace textarea resize logic with useTextareaResize hook for automatic height adjustment
- Add comprehensive refactoring documentation with usage examples and guidelines

* Refactor inputbar drag-drop and paste handling into custom hooks

- Extract paste handling logic into usePasteHandler hook
- Extract drag-drop file handling into useFileDragDrop hook
- Remove inline drag-drop state and handlers, use hook interfaces
- Clean up dependencies and callback optimizations

* Refactor Inputbar component to use InputbarCore composition

- Extract complex UI logic into InputbarCore component for better separation of concerns
- Remove intermediate wrapper component and action ref forwarding pattern
- Consolidate focus/blur handlers and simplify component structure

* Refactor Inputbar to expose actions via ref for external control

- Extract action handlers into ProviderActionHandlers interface and expose via ref
- Split component into Inputbar wrapper and InputbarInner implementation
- Update useEffect to sync inner component actions with ref for external access

* feat: inputbar core

* refactor: Update QuickPanel integration across various tools

* refactor: migrate to antd

* chore: format

* fix: clean code

* clean code

* fix i18n

* fix: i18n

* relative path

* model type

* 🤖 Weekly Automated Update: Nov 09, 2025 (#11209)

feat(bot): Weekly automated script run

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>
Co-authored-by: SuYao <sy20010504@gmail.com>

* format

* fix

* fix: format

* use ripgrep

* update with input

* add common filters

* fix build issue

* format

* fix error

* smooth change

* adjust

* support listing dir

* keep list files when focus and blur

* support draft save

* Optimize the rendering logic of session messages and input bars, and simplify conditional judgments.

* Upgrade to agentId

* format

* 🐛 fix: force quick triggers for agent sessions

* revert

* fix migrate

* fix: filter

* fix: trigger

* chore packages

* feat: 添加过滤和排序功能,支持自定义函数

* fix cursor bug

* fix format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: beyondkmp <beyondkmp@gmail.com>
Co-authored-by: kangfenmao <kangfenmao@qq.com>
2025-11-12 20:04:58 +08:00
MyPrototypeWhat
649f9420a4 feat: add @cherrystudio/ai-sdk-provider package and integrate (#10715)
* feat: add @cherrystudio/ai-sdk-provider package and integrate with CherryIN

- Introduced the @cherrystudio/ai-sdk-provider package, providing a CherryIN routing solution for AI SDKs.
- Updated configuration files to include the new provider.
- Enhanced provider initialization to support CherryIN as a new AI provider.
- Added README and documentation for usage instructions.

* chore: remove deprecated @ai-sdk/google dependency and clean up package files

- Removed the @ai-sdk/google dependency from package.json and yarn.lock as it is no longer needed.
- Simplified the createGeminiModel function in index.ts for better readability and maintainability.

* feat: update CherryIN provider integration and dependencies

- Updated @ai-sdk/anthropic and @ai-sdk/google dependencies to their latest versions in package.json and yarn.lock.
- Introduced a new CherryInProvider implementation in cherryin-provider.ts, enhancing support for CherryIN API.
- Refactored provider initialization to include CherryIN as a supported provider in schemas.ts and options.ts.
- Updated web search plugin to utilize the new CherryIN provider capabilities.
- Cleaned up and organized imports across various files for better maintainability.

* chore: clean up tsconfig and remove unnecessary nullish coalescing in CherryIn provider

- Simplified tsconfig.json by consolidating exclude and include arrays.
- Removed nullish coalescing in cherryin-provider.ts for cleaner header handling in model initialization.

* fix: remove console.log from webSearchPlugin to clean up code

- Eliminated unnecessary console.log statement in the webSearchPlugin to enhance code clarity and maintainability.

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

* chore: update yarn.lock with new package versions and dependencies

- Added new versions for @ai-sdk/anthropic, @ai-sdk/google, @ai-sdk/provider-utils, and eventsource-parser.
- Updated dependencies and peerDependencies for the newly added packages.

* feat: enhance CherryIn provider with chat model support and custom fetch logic

- Introduced CherryInOpenAIChatLanguageModel to handle chat-specific configurations.
- Updated createChatModel to support CherryIn chat models.
- Modified webSearchPlugin to accommodate both 'cherryin' and 'cherryin-chat' provider IDs.
- Added 'cherryin-chat' provider ID to schemas and provider configurations.
- Adjusted provider factory to correctly set provider ID for chat mode.
- Enhanced web search utility to handle CherryIn chat models.

* 🐛 fix: resolve cherryin provider lint errors and web search config

- Add fetch global variable declaration for ai-sdk-provider in oxlintrc
- Fix endpoint_type mapping fallback logic in cherryin provider
- Add error handling comment for better code readability

* chore(dependencies): update AI SDK packages and patches

- Added new versions for @ai-sdk/anthropic, @ai-sdk/google, and @ai-sdk/provider-utils in yarn.lock.
- Updated @ai-sdk/openai dependency to use a patch version in package.json.
- Included @cherrystudio/ai-sdk-provider as a new dependency in the workspace.

* chore(dependencies): update peer dependencies and installation instructions

- Removed specific versions of @ai-sdk/anthropic and @ai-sdk/google from package.json and yarn.lock.
- Updated peer dependencies in package.json to include @ai-sdk/anthropic, @ai-sdk/google, and @ai-sdk/openai.
- Revised installation instructions in README.md to reflect the new dependencies.

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-12 18:16:27 +08:00
MyPrototypeWhat
d82e004f57 feat(design-reference): restructure color tokens and remove outdated conversion log
- Deleted the outdated CONVERSION_LOG.md file to streamline documentation.
- Introduced new HSLA color files for primitive, semantic, and status colors, enhancing color management.
- Updated theme and token files to utilize Oklch color format for improved color representation.
- Refactored radius and color tokens for consistency and maintainability across the design system.
2025-11-12 18:14:18 +08:00
MyPrototypeWhat
aa13ad4fac feat(checkbox): export CheckedState type and add checkbox/combobox to component index
- Exported CheckedState type from the checkbox component for better type management.
- Added checkbox and combobox components to the main component index for easier access.
- Updated Storybook examples to utilize the CheckedState type for controlled checkbox states.
2025-11-12 15:04:50 +08:00
MyPrototypeWhat
02d79f47b3 feat(checkbox): add Radix UI checkbox component with Storybook examples
- Introduced a new checkbox component utilizing Radix UI, allowing for customizable sizes and states.
- Implemented styles using class-variance-authority for consistent design across different sizes (sm, md, lg).
- Added comprehensive Storybook stories demonstrating various use cases, including default, checked, disabled, and controlled states.
- Updated package.json and yarn.lock to include the new Radix UI checkbox dependency.
2025-11-12 14:58:14 +08:00
MyPrototypeWhat
75c0923636 feat(radioGroup): enhance RadioGroup component with size variants and add Storybook examples
- Introduced size variants for RadioGroupItem using class-variance-authority for better customization.
- Updated RadioGroupItem to accept size prop and adjusted styles accordingly.
- Added comprehensive Storybook stories for various use cases, including default, disabled, and size variations, to demonstrate component functionality and usage.
2025-11-12 14:26:25 +08:00
MyPrototypeWhat
7dd1ecd4a5 feat(storybook): add background options for light and dark themes
- Introduced background parameters in Storybook preview configuration to support light and dark themes.
- Defined specific color values for each theme to enhance visual consistency during component development.
2025-11-12 14:26:09 +08:00
Xiang, Haihao
2552d97ea7 fix: ensure the user can select any image in NewApiPage (#11238)
NewApiPage always show the first image in filteredPaintings. As a
result, the user is unable to select other images. This issue was
introduced in commit 0502ff4.
2025-11-12 13:30:23 +08:00
Phantom
803f4b5a64 fix(migrate): use provider apiHost for new-api (#11244)
fix(migrate): use provider apiHost for new-api case instead of hardcoded value
2025-11-12 10:05:21 +08:00
beyondkmp
31f8fff6e2 chore: update claude code plugins (#11237)
* chore: update claude code plugins

* update version

---------

Co-authored-by: Payne Fu <payne@Paynes-MacBook-Pro.local>
2025-11-11 19:19:30 +08:00
MyPrototypeWhat
a2299fa2ab style(combobox, select): update styles to use Tailwind CSS utility classes
- Refactored the combobox and select components to utilize Tailwind CSS utility classes for consistent styling.
- Added 'text-foreground' class to enhance text visibility in both components.
- Streamlined the default styles for better maintainability and adherence to the new design system.
2025-11-11 17:24:47 +08:00
MyPrototypeWhat
a830d05790 fix(tailwind): dynamically import Tailwind CSS in Vite config
- Updated the Electron Vite configuration to dynamically import Tailwind CSS for improved performance.
- Removed the direct import of Tailwind CSS from the plugins array to streamline the build process.
2025-11-11 17:17:23 +08:00
MyPrototypeWhat
8429e678bc style(tailwind): migrate to Tailwind CSS and update theme handling
- Integrated Tailwind CSS into the project by adding necessary imports and configurations.
- Updated CSS files to reflect the transition to Tailwind, including commenting out old styles and adjusting theme-related attributes.
- Changed theme mode handling in the ThemeProvider and CitationBlock components for consistency with the new class-based approach.
2025-11-11 17:03:14 +08:00
MyPrototypeWhat
91215c899d style(tailwind): add source import for UI components in tailwind.css
- Included a new source import statement for UI components to enhance styling capabilities.
- Maintained existing imports while ensuring compatibility with the updated structure.
2025-11-11 13:56:58 +08:00
fullex
1309b194e9 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-11 12:03:35 +08:00
MyPrototypeWhat
1b1f85b35f fix(navbar): remove duplicate placement attribute in Tooltip component
- Simplified Tooltip component in ChatNavbar and Navbar by removing redundant 'placement' attribute.
- Ensured consistent behavior across both components while maintaining functionality.
2025-11-11 11:31:43 +08:00
fullex
4407c0f675 refactor(oauth): update language retrieval in OAuth callback
- Replaced the configManager.getLanguage() method with getAppLanguage() for improved language handling.
- Adjusted imports to reflect the new language utility structure.
2025-11-11 11:19:06 +08:00
MyPrototypeWhat
30947c6bc1 refactor(select): replace Selector component with new Select implementation in SettingsTab
- Updated SettingsTab to utilize the new Select component instead of the deprecated Selector.
- Enhanced Select integration with SelectTrigger, SelectContent, SelectItem, and SelectValue for improved functionality.
- Removed Selector imports and related code to streamline the component structure.
- Adjusted styles and layout for better user experience in the settings interface.
2025-11-11 11:01:48 +08:00
MyPrototypeWhat
0b3cefb125 style(select): update styles for Select component items and content
- Adjusted border radius for SelectContent to 'rounded-2xs' for a more modern look.
- Enhanced SelectItem styles to include a background color for checked state.
- Updated CheckIcon color to 'text-primary' for better visibility in the SelectItem.
2025-11-11 10:46:20 +08:00
SuYao
2663cb19ce Chore/aisdk (#11232)
* chore(dependencies): update AI SDK dependencies to latest versions

* chore(patches): update AI SDK patches for Hugging Face, OpenAI, and Google
2025-11-11 00:09:26 +08:00
Pleasure1234
ce5d46bfc7 fix: remove explicit Content-Type header in file upload (#11231)
The Content-Type header was removed from the fetch request when uploading files. This change may allow the server to infer the correct content type or handle uploads more flexibly.
2025-11-10 23:28:38 +08:00
kangfenmao
c1fa24522d chore(release): update release notes for v1.7.0-beta.5
- Add MCPRouter provider and MCP marketplace features
- Improve UI optimization and MCP OAuth callback
- Fix various bugs including Agent allowed_tools inheritance
2025-11-10 20:19:40 +08:00
亢奋猫
2f66f5b511 refactor(AssistantPresetsPage): added assistants subscribe settings to AssistantPresetsPage (#11184)
refactor(DataSettings, MCPSettings, AssistantPresetsPage): clean up imports and enhance UI components

- Removed unused imports and components from DataSettings for better clarity.
- Updated MCPSettings layout by introducing a new Container styled with Scrollbar for improved scrolling.
- Added AssistantsSubscribeUrlSettings component to manage subscription URLs in AssistantPresetsPage, enhancing user interaction.
- Adjusted button styles and layout in AssistantPresetsPage for a more cohesive design.
2025-11-10 20:10:38 +08:00
MyPrototypeWhat
b382b06c57 feat(select): introduce new Select component and related features
- Added a new Select component based on Radix UI, including SelectTrigger, SelectContent, SelectItem, and SelectValue.
- Implemented support for groups and separators within the Select component.
- Updated package.json to include @radix-ui/react-select as a dependency.
- Removed deprecated Selector and SearchableSelector components to streamline the codebase.
- Added stories for the Select component to showcase various use cases and configurations.
2025-11-10 19:42:33 +08:00
MyPrototypeWhat
8246f46e7d fix(Button): update import path for Button component to reflect new structure 2025-11-10 19:35:46 +08:00
亢奋猫
2d8555c326 fix(agents): inherit allowed_tools from Agent when creating Session (#11201)
When creating a Session under an Agent, the Session should inherit the Agent's allowed_tools configuration. Previously, the allowed_tools parameter was missing from the Session creation API call, causing inconsistency between Agent and Session configurations.

Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-10 18:44:33 +08:00
fullex
f32fa08c41 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-10 18:44:02 +08:00
Konjac-XZ
e2c8edab61 fix: incorrect spelling caused Gemini endpoint’s thinking budget to fail (#11217) 2025-11-10 16:42:34 +08:00
kangfenmao
5e0a66fa1f docs(README): update AI Web Service Integration section and remove public beta notice
- Added a hyperlink to Poe in the AI Web Service Integration list for better accessibility.
- Removed the public beta notice for the Enterprise Edition to streamline the documentation.
- Updated the cost section to include a link to the AGPL-3.0 License for clarity.
2025-11-10 15:44:29 +08:00
亢奋猫
bc8b0a8d53 feat(agent): add permission mode display component for empty session state (#11204)
Replace empty state text with a visual permission mode display card that shows:
- Permission mode icon with unique colors for each mode (default, plan, acceptEdits, bypassPermissions)
- Permission mode title and description
- Clickable to navigate directly to tooling settings tab

Replace loading text with Ant Design Spin component for better UX.
2025-11-10 11:26:36 +08:00
fullex
e43562423e refactor: remove unused files and configurations (#11176)
* ♻️ refactor: remove unused resources/js directory and references

Remove legacy resources/js directory (bridge.js and utils.js) that was left over after minapp.html removal in commit 461458e5e. Also update .oxlintrc.json to remove the unused resources/js/** file pattern.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* ♻️ refactor: remove additional unused files

- Remove duplicate ipService.js (superseded by TypeScript version in src/main/utils/)
- Remove unused components.json (shadcn config with non-existent target directory)
- Remove unused context-menu.tsx component (no imports found)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-10 11:14:32 +08:00
亢奋猫
120ac122eb fix(ui): resolve sidebar tooltip overlap with window controls on macOS (#11216)
Fixes #11125

Add placement="right" to sidebar toggle tooltips in ChatNavbar, Navbar,
and Notes HeaderNavbar to prevent tooltips from overlapping with macOS
window control buttons (minimize, maximize, close) in the top-left corner.

This ensures tooltips appear to the right of the toggle buttons rather
than above them, avoiding overlap with native window controls.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 23:24:35 +08:00
Phantom
9013fcba14 fix(useMessageOperations): skip timestamp update for UI-only changes (#10927)
Prevent unnecessary message updates when only UI-related states change by checking the update keys and skipping timestamp updates in those cases
2025-11-09 18:17:34 +08:00
Phantom
c32f4badbd fix(ErrorBlock): reorder field (#11057)
feat(ErrorBlock): add responseBody display above requestBodyValues

Move responseBody display to appear before requestBodyValues for better error flow readability
2025-11-09 17:53:05 +08:00
亢奋猫
66f66fe08e fix: prevent MCP card description text from overflowing dialog width (#11203)
* fix: prevent MCP card description text from overflowing dialog width

Add whitespace-pre-wrap and break-all classes to the MCP server description
text in Agent Settings to ensure long descriptions wrap properly within the
dialog bounds instead of causing layout overflow issues.

Generated with [Claude Code](https://claude.com/claude-code)

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

* feat: display MCP server logo in Agent Settings tooling section

Add logo display support for MCP servers in the Agent Settings tooling
section. When a server has a logoUrl defined, it will now be shown next
to the server name as a 20x20px rounded image, matching the design
pattern used in MCPSettings.

Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 17:50:41 +08:00
亢奋猫
d5826c2dc7 fix(ui): truncate long Bash command in tag with popover (#11200)
* 🐛 fix(ui): truncate long Bash command in tag with popover

Add automatic truncation for Bash commands exceeding 200 characters in the tag display. When truncated, users can hover over the tag to view the full command in a popover.

- Add MAX_TAG_LENGTH constant (200 chars)
- Implement command truncation logic
- Add Popover component for full command display on hover
- Prevent UI overflow issues with long commands

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* ♻️ refactor(ui): reduce MAX_TAG_LENGTH to 100 for smaller screens

Reduce the command truncation threshold from 200 to 100 characters to better support smaller screen sizes and improve readability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* docs: remove emoji requirement from conventional commits

Update commit message guidelines to use standard Conventional Commit format without emoji prefixes for better compatibility and consistency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 12:27:15 +08:00
亢奋猫
85a628f8dd style(ui): center plugin browser tabs (#11205)
💄 style(ui): center plugin browser tabs

Center the tab items in the plugin browser component for better visual alignment and improved user experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 12:06:50 +08:00
cheng chao
ed453750fe fix(mcp): resolve OAuth callback page hanging and add i18n support (#11195)
- Fix OAuth callback server not sending HTTP response, causing browser to hang
- Add internationalization support for OAuth callback page (10 languages)
- Simplify callback page design with clean white background
- Improve user experience with localized success messages

Changes:
- src/main/services/mcp/oauth/callback.ts: Add HTTP response to OAuth callback
- src/renderer/src/i18n/: Add callback page translations for all supported languages

Signed-off-by: charles <kidccc@gmail.com>
2025-11-09 01:45:25 +08:00
亢奋猫
57d9a31c0f refactor(migrate): consolidate migrations into version 172 (#11194)
* refactor(migrate): consolidate migrations into version 172

Consolidates migrations 162-166 into a single migration 172 to fix data
inconsistencies between release/v1.6.x and v1.7.0-x versions. This
ensures a single, consistent migration path and corrects data deviations
that occurred during version upgrades.

Changes:
- Remove separate migrations 162-166
- Add consolidated migration 172 that includes:
  - Mini app additions (ling, huggingchat)
  - OCR provider updates (ovocr)
  - Agent to preset migration
  - Sidebar icon updates (agents -> store)
  - LLM provider Anthropic API host configurations
  - Assistant preset settings initialization

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

* refactor(store): update persist version to 172

Update the redux-persist version number from 171 to 172 to match the
consolidated migration version.

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

* fix(migrate): add missing break statement in switch case

Add missing break statement after 'grok' case to prevent fall-through
to 'cherryin' case. Also add break statement for 'longcat' case.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 00:31:35 +08:00
亢奋猫
58afbe8a79 refactor(config): optimize oxlint configuration by removing redundant default rules (#11192)
Remove ~60 redundant rule declarations that match oxlint's default behavior.
This reduces the config file by 28% (211 -> 152 lines) while maintaining
identical linting behavior.

Changes:
- Remove default error-level rules (constructor-super, no-debugger, etc.)
- Retain only custom configurations that differ from defaults
- Keep all environment overrides and plugin settings unchanged
- Preserve all modified severity levels (warn) and disabled rules (off)

Benefits:
- Improved readability: clearly shows project-specific lint strategy
- Reduced maintenance: no need to sync with oxlint default updates
- Smaller config: 46% fewer rule declarations (130 -> 70 rules)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 00:31:20 +08:00
亢奋猫
9a10516b52 chore: update bun and uv versions (#11193)
* chore: update bun and uv versions

- Update bun from 1.2.17 to 1.3.1
- Update uv from 0.7.13 to 0.9.5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor: update UV installer to support tar.gz format

- Update UV package mappings from .zip to .tar.gz for macOS and Linux
- Add RISCV64 Linux platform support
- Implement dual extraction logic:
  - tar.gz extraction for macOS/Linux using tar command
  - zip extraction for Windows using StreamZip
- Flatten directory structure during extraction
- Maintain executable permissions on Unix-like systems

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* 🐛 fix: correct error handling in UV installer

Remove ineffective error code 102 return from nested function.
Chmod errors now properly propagate to outer try-catch block.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-09 00:31:00 +08:00
Phantom
e268e69597 refactor(config): centralize home directory constant to shared config (#11158)
Replace hardcoded '.cherrystudio' directory references with HOME_CHERRY_DIR constant
2025-11-07 22:24:05 +08:00
kangfenmao
56df52d850 Merge branch 'main' into v2
# Conflicts:
#	src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServerList.tsx
#	src/renderer/src/pages/settings/MCPSettings/McpProviderSettings.tsx
#	src/renderer/src/pages/settings/MCPSettings/McpServersList.tsx
#	src/renderer/src/pages/settings/MCPSettings/McpSettingsNavbar.tsx
#	src/renderer/src/pages/settings/MCPSettings/index.tsx
#	src/renderer/src/pages/settings/MCPSettings/providers/config.ts
2025-11-07 19:34:45 +08:00
MyPrototypeWhat
846a7f5ecf refactor(button & combobox): enhance styling and accessibility
- Updated button variants for improved hover effects and accessibility, including aria-loading support.
- Refined combobox trigger styles for better visibility and consistency, including adjustments to error state styling and input placeholder appearance.
- Improved overall class management and organization for both components.
2025-11-07 19:29:06 +08:00
kangfenmao
10e78ac60e refactor(MCPSettings): update styled components and enhance server synchronization
- Changed RightContainer from Scrollbar to a standard div for layout adjustments.
- Updated DetailContainer to use Scrollbar for improved scrolling behavior.
- Modified server synchronization logic across multiple providers to include allServers in the results, enhancing server management capabilities.
- Refactored provider configurations to ensure consistency and support for new server data structure.
2025-11-07 19:22:58 +08:00
kangfenmao
44b2b859da feat(MCPRouter): add MCPRouter provider support and integration
- Introduced MCPRouter provider with token management and server synchronization functionalities.
- Added MCPRouter logo to settings page for visual representation.
- Updated provider configuration to include MCPRouter details and API interactions.
- Implemented functions for saving, retrieving, and clearing MCPRouter tokens, along with server synchronization logic.
2025-11-07 18:41:15 +08:00
kangfenmao
bfef0c5580 feat(MCPSettings): enhance MCP server management and localization support
- Updated auto-translation script to allow configurable max concurrent translations and delay via environment variables.
- Added new translations for "discover", "fetch", "marketplaces", "providers", and "servers" across multiple locales (en-us, zh-cn, zh-tw, de-de, el-gr, es-es, fr-fr, ja-jp, pt-pt, ru-ru).
- Improved MCPSettings UI by adjusting layout and adding a new provider settings component for better server management.
- Refactored MCP server list and market list components for improved usability and styling consistency.
2025-11-07 18:01:55 +08:00
MyPrototypeWhat
f2c2a27622 refactor(combobox & tailwind): update styling and variable management
- Modified default combobox trigger styles for improved visibility and consistency.
- Updated background and text colors in the combobox options for better accessibility.
- Cleaned up unused CSS variables in tailwind.css, retaining only those necessary for theme usage.
- Enhanced comments for clarity in the CSS files.
2025-11-07 17:30:12 +08:00
MyPrototypeWhat
348e0dfc80 fix(theme.css): standardize import syntax for tailwindcss 2025-11-07 17:17:24 +08:00
MyPrototypeWhat
77c848035d feat(tokens): introduce design tokens for colors, spacing, typography, and radius
- Added new CSS files for design tokens including colors, spacing, typography, and border radius.
- Updated theme.css to import the new tokens and ensure proper usage in the UI.
- Enhanced the theme structure to support light and dark modes with semantic color mappings.
- Introduced a build script to generate theme from tokens for easier management.
2025-11-07 17:12:34 +08:00
fullex
1e8055031a Merge branch 'main' of github.com:CherryHQ/cherry-studio 2025-11-07 12:02:35 +08:00
fullex
8e33ff8d90 docs: update test plan documentation to clarify upgrade behavior for RC and Beta channels 2025-11-07 12:02:28 +08:00
MyPrototypeWhat
cd6a38ebeb fix(tailwindCSS): add experimental classRegex for improved class management 2025-11-07 11:26:00 +08:00
MyPrototypeWhat
b57ed07d00 refactor(button & combobox): improve styling and class management
- Adjusted button outline variant for consistency in dark mode styling.
- Removed unnecessary background color from combobox trigger for cleaner appearance.
- Updated comments in the theme CSS file for clarity and consistency.
2025-11-07 11:04:12 +08:00
kangfenmao
a619000340 chore: update v1.7.0-beta.4 release notes
Update electron-builder.yml with release notes covering:
- UI framework upgrade with improved performance and UX
- New features: AWS Bedrock API key support, SophNet provider, auto session rename, TopP parameter, and reasoning effort control
- Improvements to UI components, quick panel, painting models, system shutdown handling, and package size optimization
- Bug fixes for provider support, i18n translations, and API issues
2025-11-06 20:51:03 +08:00
kangfenmao
f7c8fb8d56 refactor: update component imports and styling for consistency
- Removed the 'no-restricted-imports' rule from ESLint configuration.
- Updated `AgentSessionInputbar` to use `icon` prop for `ActionIconButton`.
- Cleaned up imports in `AssistantsTab`, `SessionItem`, and `DataSettings` components.
- Adjusted button styling in `UnifiedAddButton` and `AboutSettings` for improved layout.
- Fixed test assertions in `WebviewSearch.test.tsx` for better accuracy.
2025-11-06 20:23:38 +08:00
kangfenmao
dae10cf673 Merge branch 'v2' of github.com:CherryHQ/cherry-studio into v2 2025-11-06 19:53:20 +08:00
kangfenmao
a50da9fc80 Merge branch 'main' into v2
# Conflicts:
#	CLAUDE.md
#	package.json
#	packages/ui/src/components/primitives/toast.ts
#	src/main/services/AppMenuService.ts
#	src/renderer/src/assets/styles/tailwind.css
#	src/renderer/src/components/Avatar/EmojiAvatarWithPicker.tsx
#	src/renderer/src/components/Buttons/ActionIconButton.tsx
#	src/renderer/src/components/ConfirmDialog.tsx
#	src/renderer/src/components/ErrorBoundary.tsx
#	src/renderer/src/components/Popups/ExportToPhoneLanPopup.tsx
#	src/renderer/src/components/Popups/agent/AgentModal.tsx
#	src/renderer/src/components/Popups/agent/SessionModal.tsx
#	src/renderer/src/components/TopView/index.tsx
#	src/renderer/src/components/UpdateDialog.tsx
#	src/renderer/src/context/HeroUIProvider.tsx
#	src/renderer/src/env.d.ts
#	src/renderer/src/hero.ts
#	src/renderer/src/hooks/useUserTheme.ts
#	src/renderer/src/pages/home/Chat.tsx
#	src/renderer/src/pages/home/Inputbar/AgentSessionInputbar.tsx
#	src/renderer/src/pages/home/Messages/Blocks/ErrorBlock.tsx
#	src/renderer/src/pages/home/Messages/Message.tsx
#	src/renderer/src/pages/home/Messages/Tools/ToolPermissionRequestCard.tsx
#	src/renderer/src/pages/home/Tabs/AssistantsTab.tsx
#	src/renderer/src/pages/home/Tabs/SessionSettingsTab.tsx
#	src/renderer/src/pages/home/Tabs/components/AddButton.tsx
#	src/renderer/src/pages/home/Tabs/components/AgentItem.tsx
#	src/renderer/src/pages/home/Tabs/components/AssistantItem.tsx
#	src/renderer/src/pages/home/Tabs/components/SessionItem.tsx
#	src/renderer/src/pages/home/Tabs/components/Sessions.tsx
#	src/renderer/src/pages/home/Tabs/components/TagGroup.tsx
#	src/renderer/src/pages/home/Tabs/components/Topics.tsx
#	src/renderer/src/pages/home/Tabs/components/UnifiedAddButton.tsx
#	src/renderer/src/pages/home/Tabs/index.tsx
#	src/renderer/src/pages/home/components/ChatNavbarContent.tsx
#	src/renderer/src/pages/home/components/SelectAgentBaseModelButton.tsx
#	src/renderer/src/pages/home/components/UpdateAppButton.tsx
#	src/renderer/src/pages/minapps/components/WebviewSearch.tsx
#	src/renderer/src/pages/notes/HeaderNavbar.tsx
#	src/renderer/src/pages/settings/AboutSettings.tsx
#	src/renderer/src/pages/settings/AgentSettings/AccessibleDirsSetting.tsx
#	src/renderer/src/pages/settings/AgentSettings/components/InstalledPluginsList.tsx
#	src/renderer/src/pages/settings/AgentSettings/components/PluginBrowser.tsx
#	src/renderer/src/pages/settings/AgentSettings/components/PluginCard.tsx
#	src/renderer/src/pages/settings/DataSettings/DataSettings.tsx
#	src/renderer/src/pages/settings/ToolSettings/ApiServerSettings/ApiServerSettings.tsx
#	src/renderer/src/pages/translate/TranslateSettings.tsx
#	src/renderer/src/services/ApiService.ts
#	src/renderer/src/store/runtime.ts
#	src/renderer/src/windows/mini/MiniWindowApp.tsx
#	src/renderer/src/windows/selection/action/entryPoint.tsx
#	yarn.lock
2025-11-06 19:53:09 +08:00
MyPrototypeWhat
7d5d9964d7 refactor(combobox): simplify default styling and enhance class management
- Removed unnecessary background color from default combobox trigger variant for cleaner styling.
- Added a white background to the combobox trigger for improved visibility.
- Updated comments in the CSS file to enhance clarity and consistency in English.
2025-11-06 18:36:12 +08:00
kangfenmao
78278ce96d refactor: remove heroui
commit 7c8bf8b591
Author: defi-failure <159208748+defi-failure@users.noreply.github.com>
Date:   Thu Nov 6 17:59:38 2025 +0800

    fix: add token usage to agent session message

commit ff8e5ddd27
Author: defi-failure <159208748+defi-failure@users.noreply.github.com>
Date:   Thu Nov 6 17:25:54 2025 +0800

    fix: close prompt stream when finish or error chunk received

commit 530e6516fd
Author: defi-failure <159208748+defi-failure@users.noreply.github.com>
Date:   Thu Nov 6 17:19:53 2025 +0800

    chore: code cleanup

commit ab21c0d56c
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 16:13:36 2025 +0800

    feat(SessionItem): implement auto-rename feature for sessions and improve context menu handling

    - Added a new context menu option to automatically rename sessions based on topics.
    - Introduced useDeferredValue for managing target session state.
    - Updated imports to include necessary thunk actions and components.
    - Enhanced API service to handle optional assistant model in message summary fetching.
    - Exported renameAgentSessionIfNeeded function for better accessibility in the store.

commit 21ea8ccf37
Merge: ab7b207d2 816a92c60
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 15:29:09 2025 +0800

    Merge branch 'main' of github.com:CherryHQ/cherry-studio into refactor/heroui-antd

    # Conflicts:
    #	src/renderer/src/pages/home/Tabs/components/AddButton.tsx
    #	src/renderer/src/pages/home/Tabs/components/SessionItem.tsx
    #	src/renderer/src/pages/home/Tabs/components/Sessions.tsx
    #	src/renderer/src/pages/home/Tabs/components/Topics.tsx
    #	src/renderer/src/pages/paintings/NewApiPage.tsx

commit ab7b207d29
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 14:50:05 2025 +0800

    refactor: streamline event listener management in useAppInit and update ToolPermissionRequestCard styling

commit 3834c5d402
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 14:21:25 2025 +0800

    refactor: enhance API server state management and remove unused initialization in useAppInit

commit a64b94a41f
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 13:21:58 2025 +0800

    refactor: update OpenAPI documentation paths to include subdirectories for better route coverage

commit 2e0ff28505
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 12:26:09 2025 +0800

    refactor: center align columns in InstalledPluginsList and set AntTable size to small

commit 84bf94e2ff
Author: defi-failure <159208748+defi-failure@users.noreply.github.com>
Date:   Thu Nov 6 12:06:09 2025 +0800

    refactor: align create agent model selection with edit agent

commit 84f2281506
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 11:29:32 2025 +0800

    refactor: integrate API server functionality into various components and enhance user notifications

commit 4e01210df4
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 10:56:38 2025 +0800

    refactor: replace ContextMenu with Dropdown in AgentItem and SessionItem components for improved context menu handling

commit 9df38c7e83
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 10:27:30 2025 +0800

    refactor: update AddButton styling to use CSS variable for border radius and remove unused settings hook

commit 251c269ab3
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 10:11:21 2025 +0800

    refactor: remove unused error handling alerts from AssistantsTab component

commit 9b9640d8d1
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 10:07:26 2025 +0800

    refactor: adjust margin styling for UnifiedAddButton component

commit edd6b11aa7
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 10:04:01 2025 +0800

    refactor: update AddButton styling based on topic position and clean up CSS for root element

commit 1c0de625d8
Author: kangfenmao <kangfenmao@qq.com>
Date:   Thu Nov 6 09:56:42 2025 +0800

    fix: update assistant addition messages for multiple languages

commit 0ea4dd4e3a
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 21:01:24 2025 +0800

    fix: init message api err

commit f3bbd4ed44
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 20:42:49 2025 +0800

    refactor: remove heroui

commit d01609fc36
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 19:08:41 2025 +0800

    refactor: migrate heroui/toast to antd message

commit f4b14dfc10
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 18:51:29 2025 +0800

    refactor: enhance Sessions component layout with styled Scrollbar and adjust UnifiedAddButton margins

commit 6ae5f69163
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 18:44:13 2025 +0800

    refactor: update PluginSettings and ToolingSettings for improved layout and functionality

commit fcb0020787
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 18:29:52 2025 +0800

    wip

commit 02265f369e
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 17:26:39 2025 +0800

    fix: error block related

commit 5e22d9d36f
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 17:14:25 2025 +0800

    fix: note head nav related

commit 3f52b7766a
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 16:45:49 2025 +0800

    chore: remove dead code

commit 484622f12b
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 16:43:12 2025 +0800

    chore: remove dead code

commit 2bceb302e0
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 15:33:25 2025 +0800

    fix: tool setting related

commit 5c455f25eb
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 13:59:33 2025 +0800

    chore: remove dead code

commit d1d1dbc046
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 13:51:41 2025 +0800

    fix: tool permission card related

commit bf4ec23ef7
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 12:22:53 2025 +0800

    fix: remove button and modal renaming

commit 47db5baeb1
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 12:20:36 2025 +0800

    fix: plugin setting related

commit 81fecce552
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 12:16:42 2025 +0800

    refactor: enhance ChatNavbarContent structure by replacing Breadcrumbs with custom layout and adding separators

commit fc64b6c611
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 12:10:48 2025 +0800

    refactor: simplify MessageAgentTools component structure by removing unnecessary wrapper div

commit e0f383a050
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 12:08:32 2025 +0800

    fix: update button classes in AddAssistantOrAgentPopup for improved cursor behavior

commit 720284262f
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 12:06:58 2025 +0800

    refactor: update AgentModal to use TopView for improved modal management and enhance form structure

commit b334a2c5be
Author: kangfenmao <kangfenmao@qq.com>
Date:   Wed Nov 5 11:40:47 2025 +0800

    refactor: replace UpdateDialog with UpdateDialogPopup for better modal handling

commit 468aebd632
Author: dev <verc20.dev@proton.me>
Date:   Wed Nov 5 10:56:40 2025 +0800

    fix: plugins related wip

commit bd4a979f62
Author: dev <verc20.dev@proton.me>
Date:   Tue Nov 4 17:46:14 2025 +0800

    fix: add button related

commit b3316a4dc8
Author: dev <verc20.dev@proton.me>
Date:   Tue Nov 4 17:18:31 2025 +0800

    fix: agent tool result related components

commit 6ca7597a98
Author: dev <verc20.dev@proton.me>
Date:   Tue Nov 4 11:12:01 2025 +0800

    fix: lint

commit 7d0f0b38a6
Author: kangfenmao <kangfenmao@qq.com>
Date:   Tue Nov 4 09:56:32 2025 +0800

    wip

commit 96a607a410
Author: kangfenmao <kangfenmao@qq.com>
Date:   Mon Nov 3 20:23:25 2025 +0800

    wip

commit 235ad16252
Author: kangfenmao <kangfenmao@qq.com>
Date:   Mon Nov 3 20:08:45 2025 +0800

    wip

commit f23fe1b9e9
Author: kangfenmao <kangfenmao@qq.com>
Date:   Mon Nov 3 19:15:01 2025 +0800

    wip

commit 28fac543fc
Author: kangfenmao <kangfenmao@qq.com>
Date:   Mon Nov 3 18:39:39 2025 +0800

    wip

commit 3cc7ee01e2
Author: kangfenmao <kangfenmao@qq.com>
Date:   Mon Nov 3 17:33:13 2025 +0800

    wip

commit 37bdf9e508
Author: kangfenmao <kangfenmao@qq.com>
Date:   Sat Nov 1 19:16:58 2025 +0800

    wip

commit 1bf5104f97
Author: kangfenmao <kangfenmao@qq.com>
Date:   Sat Nov 1 12:12:01 2025 +0800

    wip
2025-11-06 18:27:43 +08:00
Phantom
76483d828e ci(i18n): change auto i18n workflow to run weekly (#11152)
* ci(i18n): change auto i18n workflow to run weekly

Update the workflow to run on a weekly schedule instead of on pull request events.
Also simplify the workflow by using yarn for dependency management and create a PR
for changes instead of committing directly to the branch.

* ci(github-actions): improve workflow step names with emojis

Use emojis in step names to enhance readability and visual scanning of workflow logs

* ci(workflow): prevent committing package.json and yarn.lock changes in i18n workflow
2025-11-06 18:25:04 +08:00
MyPrototypeWhat
059f821584 refactor(button & combobox): update size properties and improve styling
- Changed button size properties to use min-height for better layout consistency.
- Simplified combobox size properties by removing height specifications.
- Enhanced combobox option rendering with improved class management for better styling.
- Updated comments in ComboboxProps to English for clarity.
2025-11-06 18:20:43 +08:00
MyPrototypeWhat
1c38e31e9e feat(theme): enhance color tokens with brand colors and update primary color references
- Added new brand color tokens for Cherry Studio ranging from 50 to 950.
- Updated primary color references to use brand colors for improved consistency.
- Introduced hover states for primary and destructive colors to enhance UI interactivity.
2025-11-06 17:45:40 +08:00
MyPrototypeWhat
12e3a22726 feat: add Combobox component with search and multi-select functionality
- Introduced a new Combobox component that supports single and multiple selections, search functionality, and customizable rendering of options.
- Implemented variants for different states (default, error, disabled) and sizes (small, default, large).
- Added a demo and Storybook stories to showcase various use cases and states of the Combobox.
2025-11-06 17:24:45 +08:00
MyPrototypeWhat
2b1269af92 chore: update Storybook dependencies to version 10.0.5 and refactor Storybook configuration for absolute paths 2025-11-06 17:24:28 +08:00
MyPrototypeWhat
c4fa975b89 style(tailwind): add cursor pointer for non-disabled buttons 2025-11-06 17:24:12 +08:00
Jake Jia
816a92c609 feat(app-menu): add full i18n support and sync lanuage with app language settings (#11131)
Previously, the macOS menu bar was always displayed in English regardless of
system language or in-app language settings. This change enables the menu bar
to dynamically follow the application's language preference.

Key changes:
- Add language change listener to automatically update menu when user switches language
- Refactor AppMenuService with proper subscription management and cleanup
- Add appMenu translations for en-us, zh-cn, and zh-tw locales
- Implement destroy method to prevent memory leaks from config subscriptions
- Convert all menu items (File, Edit, View, Window, Help) to use localized labels

The menu bar now respects the in-app language setting and updates in real-time
when users change their preferences, providing a consistent multilingual experience.
2025-11-06 14:46:42 +08:00
beyondkmp
83e4d4363f fix: add Perplexity provider support and update API host formatting (#11162)
* feat: add Perplexity provider support and update API host formatting

- Introduced `isPerplexityProvider` function to identify Perplexity providers.
- Updated `formatProviderApiHost` to handle Perplexity provider API host formatting.
- Added unit tests for Perplexity provider configuration to ensure correct API host formatting behavior.

* fix: add 'perplexity' to unsupported API version providers list
2025-11-06 10:43:33 +08:00
fullex
1b67b851b7 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-05 16:24:06 +08:00
fullex
811e702568 fix: i18n 2025-11-05 16:14:28 +08:00
Phantom
1103449a4f fix: wrong migration in #10727 (#11151) 2025-11-05 14:33:07 +08:00
beyondkmp
56c7a7f066 🐛 fix: resolve TypeScript type conflicts and React hooks warnings (#11148)
* 🐛 fix: resolve TypeScript type conflicts and React hooks warnings

- Add @smithy/types@4.7.1 to resolutions to unify AWS SDK dependencies
- Wrap updatePaintingState in useCallback to fix exhaustive-deps warning
- Fix AWS Bedrock client type incompatibility issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub Action <action@github.com>
2025-11-05 14:19:14 +08:00
Phantom
caa59c4c50 refactor(Topics & Sessions): Style and code structure adjustments (#10868)
* refactor(Tabs): extract shared styled components into separate file

Move common styled components (ListItem, ListItemNameContainer, ListItemName, ListItemEditInput) from SessionItem.tsx and Topics.tsx into shared.tsx to improve code reuse and maintainability

* refactor(components): extract ListContainer component for shared tab layouts

Create reusable ListContainer component to standardize layout styling across tabs
Replace manual div containers in Sessions and Topics components with new ListContainer

* refactor(ListItem): convert styled component to Tailwind CSS function component

- Convert ListItem from styled-components to Tailwind CSS function component
- Maintain all original styling and hover/active states
- Use HTMLDivElement props interface for proper TypeScript typing
- Preserve CSS custom properties for theme variables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor(ListItemNameContainer): convert styled component to Tailwind CSS function component

- Convert ListItemNameContainer from styled-components to Tailwind CSS function component
- Simplify layout styles using Tailwind's utility classes
- Use HTMLDivElement props interface for proper TypeScript typing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor(ListItemName): convert styled component to Tailwind CSS function component

- Convert ListItemName from styled-components to Tailwind CSS function component
- Use inline styles for webkit-specific line clamping properties
- Remove complex animations from component definition (can be added via CSS classes)
- Use HTMLDivElement props interface for proper TypeScript typing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor(ListItemEditInput): convert styled component to Tailwind CSS function component

- Convert ListItemEditInput from styled-components to Tailwind CSS function component
- Use proper InputHTMLAttributes type for input elements
- Remove styled-components import as no longer needed
- Maintain all original styling using Tailwind utility classes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor(components): improve type safety and class ordering in shared components

- Replace HTMLAttributes with more specific ComponentProps types
- Reorder class names for better readability and consistency

* refactor(components): update styling and class handling in list items

- Replace deprecated classNames utility with cn from @heroui/react
- Consolidate style properties into className using cn
- Improve CSS selector syntax for better specificity
- Standardize padding and border radius values

* Revert "refactor(ListItemName): convert styled component to Tailwind CSS function component"

This reverts commit 196136068d.

* style(shared): increase font size and remove redundant padding

The font size was increased from 13px to 14px for better readability. Redundant padding in ListItemEditInput was removed to maintain consistent styling.

* refactor(AddButton): simplify component by removing FC type and inline props

Remove unnecessary FC type declaration and inline the Props interface with ButtonProps. Also clean up prop spreading by moving it to the end of the component.

* style(Topics): remove redundant className and add overflow styles

* refactor(components): extract MenuButton to shared components

Move MenuButton implementation from individual components to shared module to reduce code duplication and improve maintainability

* refactor(PendingIndicator): convert styled component to Tailwind CSS function component

- Convert PendingIndicator from styled-components to Tailwind CSS function component
- Use ComponentPropsWithoutRef<'div'> for consistent TypeScript typing
- Replace styled-components attrs with Tailwind animate-pulse class
- Use CSS custom properties for pulse-size variable
- Remove styled-components import as no longer needed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor(components): replace styled indicators with shared StatusIndicator

Consolidate PendingIndicator and FulfilledIndicator into a single StatusIndicator component with variant support

* style(shared.tsx): adjust border styles for singlealone active state

* refactor: use type-only imports for react props

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-05 14:14:40 +08:00
fullex
2546dfbe5d chore: update Node.js version to 22 and Yarn version to 4.9.1 across workflows and documentation 2025-11-05 12:54:30 +08:00
beyondkmp
5fea202a7d fix: add PowerMonitorService for system shutdown handling (#11115)
* feat: add PowerMonitorService for system shutdown handling

- Add PowerMonitorService to monitor system shutdown events
- Use @paymoapp/electron-shutdown-handler for Windows platform
- Use Electron's powerMonitor for macOS and Linux platforms
- Support registering multiple shutdown handlers via dependency injection
- Register shutdown handlers in ipc.ts to disable auto-update and save data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* format code

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-04 18:56:09 +08:00
fullex
7dce1d776b feat: app's version history log (#11097)
* feat: integrate version tracking in app initialization

- Added versionService to record the current version during app startup.
- This change prepares for upcoming data refactoring in version 2.

* fix: lint from other PRs & format

* feat: enhance version tracking with meaningful change detection

- Updated VersionService to check for changes in version, OS, environment, packaged status, and install mode before recording a new entry.
- Improved logging to reflect whether version information has changed or remained the same.
2025-11-04 14:13:07 +08:00
beyondkmp
346af4d338 fix: add CherryAI provider support and update API host formatting (#11135)
* fix: add CherryAI provider support and update API host formatting

* format code

* add ut

* format code
2025-11-04 12:59:14 +08:00
Zephyr
abd5d3b96f feat: amazon bedrock request use bedrock api key (#10727)
* feat: amazon bedrock request use bedrock api key

* feat: ai-core/provider support bedrock api key

* refactor: extract AWS Bedrock auth type and remove redundant state

* feat: add bedrock reasoning support

Add AWS Bedrock-specific reasoning parameter handling to support Extended Thinking feature for Claude models via Bedrock API.

Changes:
- Add `buildBedrockProviderOptions` function in options.ts to handle Bedrock-specific provider options
- Add `getBedrockReasoningParams` function in reasoning.ts to generate reasoning config with budget tokens
- Register 'bedrock' case in provider options switch to route to Bedrock-specific builder
- Reuse `getAnthropicThinkingBudget` helper for consistent token budget calculation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* feat: add migration for Bedrock auth type and API key fields

* refactor: replace any type with BedrockRuntimeClientConfig in AWS Bedrock client

* fix: bug fix

* fix: lint error

* fix: bedrock reasoning

* chore: bump persisted reducer version to 171

* Update src/renderer/src/store/migrate.ts

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: icarus <eurfelux@gmail.com>
2025-11-03 21:05:10 +08:00
Phantom
49bd298d37 feat(InputbarTools): add reasoning effort button to quick panel (#10959)
Add new menu item with lightbulb icon that opens the reasoning effort quick panel when clicked
2025-11-03 20:36:52 +08:00
Phantom
714a28ac29 fix(QuickPanel): Hide the options that should be hidden in the quick panel. (#10931)
* feat(QuickPanel): add hidden property to list items

Add support for hiding QuickPanel items by introducing a hidden property. This allows conditional visibility of items like the knowledge base button based on application state.

* docs(types): clarify settings field comment in Assistant type
2025-11-03 20:34:24 +08:00
MyPrototypeWhat
4ef4297391 refactor: update imports and button event handlers in story files
- Refactored import statements in CodeEditor, ThinkingEffect, ErrorBoundary, and Spinner story files for consistency and clarity.
- Changed button event handlers from `onPress` to `onClick` to align with standard React practices.
- Improved type imports for better organization and maintainability.
2025-11-03 19:17:50 +08:00
MyPrototypeWhat
292f7f7b75 chore: remove unused CSS files and update Storybook configurations
- Deleted the todocss.css file as it was no longer needed.
- Updated Storybook main.ts to include path aliasing for better module resolution.
- Removed deprecated stories and components, streamlining the codebase.
- Added new stories for CodeEditor, Ellipsis, ExpandableText, and other components to enhance documentation and showcase functionality.
2025-11-03 18:31:48 +08:00
beyondkmp
0cf81c04c8 chore: update electron-builder.yml to exclude additional configuration files from build (#11129)
* chore: update electron-builder.yml to exclude additional configuration files from build

* delete all hide files
2025-11-03 17:54:29 +08:00
kangfenmao
4186e9c990 feat: add support for TopP in model capabilities and update parameter builder to utilize it 2025-11-03 16:37:12 +08:00
MyPrototypeWhat
e56edbaa4f feat: enhance Button component with loading state and custom loading icon
- Added loading state support to the Button component, allowing for a spinner to be displayed when the button is in a loading state.
- Introduced props for custom loading icons and adjusted button behavior to disable when loading.
- Updated various components to utilize the new loading feature for better user experience during asynchronous actions.
2025-11-03 16:30:45 +08:00
kangfenmao
d8f68a6056 feat: initialize painting model with first available option and update default provider to 'cherryin' 2025-11-03 15:12:58 +08:00
kangfenmao
11bf50e722 fix(i18n): improve label retrieval for paintings image size options 2025-11-03 14:45:21 +08:00
MyPrototypeWhat
e06142b89a chore: remove deprecation comments from EditableNumber and Sortable components
- Removed deprecation comments from EditableNumber and Sortable components, as they were previously marked for removal due to low usage and dependency conflicts.
2025-11-03 14:24:22 +08:00
MyPrototypeWhat
fb6b326947 chore: mark multiple components and icons as deprecated
- Added deprecation comments to several components and icons due to low usage (≤2 times), indicating plans for removal in future versions.
- Components affected include EditableNumber, MaxContextCount, Sortable, ThinkingEffect, FileIcons, ToolIcon, and others.
- Suggested alternatives or direct usage of other components where applicable.
2025-11-03 13:41:00 +08:00
kangfenmao
32a84311aa feat: add SophNet LLM provider 2025-11-03 13:28:40 +08:00
beyondkmp
6eaa2b2461 refactor: remove main window dependency from PythonService and utilize WindowService for window management (#11116)
* refactor: remove main window dependency from PythonService and utilize WindowService for window management

* format code
2025-11-03 13:09:40 +08:00
MyPrototypeWhat
f9b7ff7d0e refactor: comment out unused CSS imports and styles
- Commented out the import of color.css in index.css.
- Commented out the universal selector in tailwind.css to prevent unintended styling, with a note for future removal after migration.
2025-11-03 11:30:58 +08:00
defi-failure
9f00f00546 chore: update v1.7.0-beta.3 release notes (#11105)
* chore: update v1.7.0-beta.3 release notes

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

* fix: code lint error

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-02 22:28:36 +08:00
SuYao
bd94d23343 refactor:Unify the naming of configuration fields in thinking, change to using underscore style. (#11106)
* refactor:Unify the naming of configuration fields in thinking, change to using underscore style.

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

* chore: lint

* fix: typecheck

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-02 19:24:23 +08:00
chenxue
5f1c14e2c0 fix(aihubmix): fix default rules missing app code (#11100)
* add imagen

* Update aihubmix.ts

* fix type

---------

Co-authored-by: zhaochenxue <zhaochenxue@bixin.cn>
2025-11-02 17:03:05 +08:00
dependabot[bot]
cdc12d5092 ci(deps): bump actions/stale from 9 to 10 (#11088)
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 08:44:53 +08:00
dependabot[bot]
e5967fd874 ci(deps): bump actions/upload-artifact from 4 to 5 (#11089)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 08:44:41 +08:00
dependabot[bot]
e2f1d80697 ci(deps): bump actions/setup-node from 4 to 6 (#11090)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 08:44:28 +08:00
fullex
14706ec4d7 fix: typecheck 2025-11-01 19:11:17 +08:00
fullex
09f2fb6538 fix: lint errors 2025-11-01 18:47:20 +08:00
fullex
62aedcaa23 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-01 18:46:38 +08:00
fullex
62ccb6105d feat: enhance CacheService and DataApiService documentation and structure
- Added detailed file overview comments to CacheService and DataApiService, clarifying their roles as infrastructure components rather than business services.
- Updated README.md to reflect the new structure and naming conventions, emphasizing the distinction between infrastructure and business logic components.
- Introduced a new TestService for API testing scenarios, providing mock data and various test cases.
- Created IBaseService interface to standardize service operations across the codebase.
- Improved organization of API handlers and services for better clarity and maintainability.
2025-11-01 18:36:28 +08:00
SuYao
28bc89ac7c perf: optimize QR code generation and connection info for phone LAN export (#11086)
* Increase QR code margin for better scanning reliability

- Change QRCodeSVG marginSize from 2 to 4 pixels
- Maintains same QR code size (160px) and error correction level (Q)
- Improves readability and scanning success rate on mobile devices

* Optimize QR code generation and connection info for phone LAN export

- Increase QR code size to 180px and reduce error correction to 'L' for better mobile scanning
- Replace hardcoded logo path with AppLogo config and increase logo size to 60px
- Simplify connection info by removing candidates array and using only essential IP/port data

* Optimize QR code data structure for LAN connection

- Compress IP addresses to numeric format to reduce QR code complexity
- Use compact array format instead of verbose JSON object structure
- Remove debug logging to streamline connection flow

* feat: 更新 WebSocket 状态和候选者响应类型,优化连接信息处理

* Increase QR code size and error correction for better scanning

- Increase QR code size from 180px to 300px for improved readability
- Change error correction level from L (low) to H (high) for better reliability
- Reduce logo size from 60px to 40px to accommodate larger QR data
- Increase margin size from 1 to 2 for better border clearance

* 调整二维码大小和图标尺寸以优化扫描体验

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

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

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

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-01 12:13:11 +08:00
fullex
5101488d65 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-01 11:01:56 +08:00
fullex
dc06c103e0 chore[lint]: add import type lint (#11091)
chore: add import type lint
2025-11-01 10:40:02 +08:00
fullex
7c0b03dbdc Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-11-01 09:46:47 +08:00
SuYao
1f0381aebe Fix/azure embedding (#11044)
* fix: update EmbeddingsFactory to use net.fetch and refactor KnowledgeService to use ModernAiProvider

* fix: remove deprecated @langchain/community dependency from package.json

* fix: add @langchain/community dependency to package.json and update yarn.lock
2025-11-01 01:52:16 +08:00
kangfenmao
fb02a61a48 feat: add AddAssistantOrAgentPopup component and update i18n translations
- Introduced a new AddAssistantOrAgentPopup component for selecting between assistant and agent options.
- Updated English, Simplified Chinese, and Traditional Chinese translations to include descriptions and titles for assistant and agent options.
- Refactored UnifiedAddButton to utilize the new popup for adding assistants or agents.
2025-10-31 23:46:51 +08:00
defi-failure
562fbb3ff7 fix: minor ui tweak of plugin installation interface (#11085)
* fix: use dropdown instead of chip filter

* fix: add padding to avoid scroll bar overlap

* fix: set max card grid col to 2

* fix: minor ui tweak for plugin card

* fix: remove redundant args

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

* fix: cleanup comments

---------

Co-authored-by: GitHub Action <action@github.com>
2025-10-31 22:28:25 +08:00
Pleasure1234
1018ad87b8 fix: cancel debounced save on file path update (#11069)
Adds cancellation of the debounced save when the active file path is updated after moving a file or folder. This prevents saving to the old path and ensures lastFilePathRef is updated accordingly.
2025-10-31 14:17:06 +00:00
kangfenmao
82ca35fc29 chore: update issue template names by removing language specification
- Modified the names of the issue templates for bug reports, feature requests, and other questions to remove the "(English)" suffix, simplifying the titles for better clarity.
2025-10-31 21:29:29 +08:00
kangfenmao
fe53b0914a feat: add enterprise section and remove license from AboutSettings
- Introduced an "Enterprise" section in the i18n files for English, Simplified Chinese, and Traditional Chinese.
- Removed the "License" section from the AboutSettings component, replacing it with a link to the enterprise website.
- Updated icons in the AboutSettings component to reflect the new structure.
2025-10-31 21:28:30 +08:00
defi-failure
67a379641f fix(agent): resolve edit modal loading race condition (#11084)
* fix(agent): resolve edit modal loading race condition

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

---------

Co-authored-by: GitHub Action <action@github.com>
2025-10-31 21:00:35 +08:00
fullex
b3dc2d0422 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-10-31 19:35:45 +08:00
MyPrototypeWhat
1828ef8997 fix: update muted foreground color variable in theme.css
- Changed the variable for muted foreground color from `--cs-foreground-secondary` to `--cs-foreground-muted` for improved clarity and consistency in styling.
2025-10-31 19:33:58 +08:00
kangfenmao
9dbc6fbf67 Revert "feat: 添加路由懒加载组件以优化页面加载性能 (#11042)"
This reverts commit dd8690b592.
2025-10-31 18:54:48 +08:00
fullex
b3f88a7fc2 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-10-31 18:29:44 +08:00
kangfenmao
8da43ab794 chore: update release notes for v1.7.0-beta.3
- Added new features including an enhanced tool permission system, plugin management, and support for various AI models.
- Improved UI elements and agent creation processes.
- Fixed multiple bugs related to session models, assistant activation, and various API integrations.
- Updated version in package.json to v1.7.0-beta.3.
2025-10-31 17:20:41 +08:00
槑囿脑袋
2a06c606e1 feat: restore data to mobile App (#10108)
* feat: restore data to App

* fix: i18n check

* fix: lint

* Change WebSocket service port to 11451

- Update default port from 3000 to 11451 for WebSocket connections
- Maintain existing service structure and client connection handling

* Add local IP address to WebSocket server configuration

- Set server path using local IP address for improved network accessibility
- Maintain existing CORS policy with wildcard origin
- Keep backward compatibility with current connection handling

* Remove local IP path and enforce WebSocket transport

- Replace dynamic local IP path with static WebSocket transport configuration
- Maintain CORS policy with wildcard origin for cross-origin connections
- Ensure reliable WebSocket-only communication by disabling fallback transports

* Add detailed logging to WebSocket connection flow

- Enhance WebSocketService with verbose connection logging including transport type and client count
- Add comprehensive logging in ExportToPhoneLanPopup for WebSocket initialization and status tracking
- Improve error handling with null checks for main window before sending events

* Add engine-level WebSocket connection monitoring

- Add initial_headers event listener to log connection attempts with URL and headers
- Add engine connection event to log established connections with remote addresses
- Add startup logs for server binding and allowed transports

* chore: change to use 7017 port

* Improve local IP address selection with interface priority system

- Implement network interface priority ranking to prefer Ethernet/Wi-Fi over virtual/VPN interfaces
- Add detailed logging for interface discovery and selection process
- Remove websocket-only transport restriction for broader client compatibility
- Clean up unused parameter in initial_headers event handler

* Add VPN interface patterns for Tailscale and WireGuard

- Include Tailscale VPN interfaces in network interface filtering
- Add WireGuard VPN interfaces to low-priority network candidates
- Maintain existing VPN tunnel interface patterns for compatibility

* Add network interface prioritization for QR code generation

- Implement `getAllCandidates()` method to scan and prioritize network interfaces by type (Ethernet/Wi-Fi over VPN/virtual interfaces)
- Update QR code payload to include all candidate IPs with priority rankings instead of single host
- Add comprehensive interface pattern matching for macOS, Windows, and Linux systems

* Add WebSocket getAllCandidates IPC channel

- Add new WebSocket_GetAllCandidates enum value to IpcChannel
- Register getAllCandidates handler in main process IPC
- Expose getAllCandidates method in preload script API

* Add WebSocket connection logging and temporary test button

- Add URL and method logging to WebSocket engine connection events
- Implement Socket.IO connect and connect_error event handlers with logging
- Add temporary test button to force connection status for debugging

* Clean up WebSocket logging and remove debug code

- Remove verbose debug logs from WebSocket service and connection handling
- Consolidate connection logging into single informative messages
- Remove temporary test button and force connection functionality from UI
- Add missing "sending" translation key for export button loading state

* Enhance file transfer with progress tracking and improved UI

- Add transfer speed monitoring and formatted file size display in WebSocket service
- Implement detailed connection and transfer state management in UI component
- Improve visual feedback with status indicators, progress bars, and error handling

* Enhance WebSocket service and LAN export UI with improved logging and user experience

- Add detailed WebSocket server configuration with transports, CORS, and timeout settings
- Implement comprehensive connection logging at both Socket.IO and Engine.IO levels
- Refactor export popup with modular components, status indicators, and i18n support

* 移除 WebSocket 连接时的冗余日志记录

* Remove dot indicator from connection status component

- Simplify status style map by removing unused dot color properties
- Delete dot indicator element from connection status display
- Maintain existing border and background color styling for status states

* Refactor ExportToPhoneLanPopup with dedicated UI components and improved UX

- Extract QR code display states into separate components (LoadingQRCode, ScanQRCode, ConnectingAnimation, ConnectedDisplay, ErrorQRCode)
- Add confirmation dialog when attempting to close during active file transfer
- Improve WebSocket cleanup and modal dismissal behavior with proper connection handling

* Remove close button hiding during QR code generation

- Eliminate `hideCloseButton={isSending}` prop to keep close button visible
- Maintain consistent modal behavior throughout export process
- Prevent user confusion by ensuring close option remains available

* auto close

* Extract auto-close countdown into separate component

- Move auto-close countdown logic from TransferProgress to dedicated AutoCloseCountdown component
- Update styling to use paddingTop instead of marginTop for better spacing
- Clean up TransferProgress dependencies by removing autoCloseCountdown

* 添加局域网传输相关的翻译文本,包括自动关闭提示和确认关闭消息

---------

Co-authored-by: suyao <sy20010504@gmail.com>
2025-10-31 16:48:09 +08:00
MyPrototypeWhat
b6dcf2f5fa Feat/add skill tool (#11051)
* feat: add SkillTool component and integrate into agent tools

- Introduced SkillTool component for rendering skill-related functionality.
- Updated MessageAgentTools to include SkillTool in the tool renderers.
- Enhanced MessageTool to recognize 'Skill' as a valid agent tool type.
- Modified handleUserMessage to conditionally handle text blocks based on skill inclusion.
- Added SkillToolInput and SkillToolOutput types for better type safety.

* feat: implement command tag filtering in message handling

- Added filterCommandTags function to remove command-* tags from text content, ensuring internal command messages do not appear in the user-facing UI.
- Updated handleUserMessage to utilize the new filtering logic, enhancing the handling of text blocks and improving user experience by preventing unwanted command messages from being displayed.

* refactor: rename tool prefix constants for clarity

- Updated variable names for tool prefixes in MessageTool and SkillTool components to enhance code readability.
- Changed `prefix` to `builtinToolsPrefix` and `agentPrefix` to `agentMcpToolsPrefix` for better understanding of their purpose.
2025-10-31 16:31:50 +08:00
MyPrototypeWhat
2c07ea0dd8 chore: update Tailwind CSS imports and adjust source paths
- Replaced the import of `theme.css` with `tailwindcss` for improved styling management.
- Adjusted the source path to include components specifically, enhancing clarity in file structure.
- Retained the import of `tw-animate-css` for animation support.
2025-10-31 16:25:11 +08:00
defi-failure
68e0d8b0f1 feat: add confirmation modal for activating protocol-installed MCP (#11070)
* feat: add confirmation modal for activating protocol-installed MCP

* fix: sync i18n

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

* chore: verify ci is working

* Revert "chore: verify ci is working"

This reverts commit a2434a397d.

---------

Co-authored-by: GitHub Action <action@github.com>
2025-10-31 16:05:02 +08:00
MyPrototypeWhat
6042ee8ca8 chore: remove outdated DESIGN_SYSTEM.md and update migration documentation
- Deleted the obsolete DESIGN_SYSTEM.md file to streamline documentation.
- Updated MIGRATION_STATUS.md to reflect the new design token namespace (`--cs-*`) and improved clarity on migration phases and principles.
- Revised README.md to correct the number of import methods and enhance usage instructions for the updated design system.
2025-10-31 15:54:29 +08:00
MyPrototypeWhat
d164d7c8bf refactor: update CSS structure and improve theme integration
- Changed the main CSS file reference from `globals.css` to `theme.css` in `components.json` for better theme management.
- Introduced `index.css` to export only CSS variables, allowing npm users to utilize design tokens without overriding Tailwind defaults.
- Removed `globals.css` as it is no longer needed with the new structure.
- Updated `package.json` to reflect changes in CSS file paths.
- Enhanced `README.md` to clarify installation and configuration steps for the new styling approach.
2025-10-31 15:31:51 +08:00
LiuVaayne
7f1c234ac1 fix(ClaudeCodeService): update environment variable names for models (#11073) 2025-10-31 14:46:24 +08:00
Phantom
c1fd23742f fix: activate assistant/agent when creating new (#11009)
* refactor: remove unused SWITCH_ASSISTANT event and related code

Clean up unused event and associated listener in HomePage component

* feat(agents): improve agent handling and state management

- Return result from useUpdateAgent hook
- Update useActiveTopic to handle null assistantId
- Add state management for active agent and topic in Tabs
- Implement afterSubmit callback in AgentModal
- Refactor agent press handling in AssistantsTab
- Clean up HomePage state management logic
- Add afterCreate callback in UnifiedAddButton

* refactor(agent): update agent and session update functions to return entities

Modify update functions in useUpdateAgent and useUpdateSession hooks to return updated entities.
Update related components to handle the new return types and adjust type definitions accordingly.

* refactor(hooks): simplify active topic hook by using useAssistant

* refactor(agent): consolidate agent update types and functions

Move UpdateAgentBaseOptions and related function types from hooks/agents/types.ts to types/agent.ts
Update components to use new UpdateAgentFunctionUnion type
Simplify component props by removing redundant type definitions

* refactor(agent): update type for plugin settings update function

* refactor(AgentSettings): simplify tooling settings type definitions

Remove unused hooks and use direct type imports instead of ReturnType
2025-10-31 14:41:07 +08:00
LiuVaayne
d792bf7fe0 🐛 fix: resolve tool approval UI and shared workspace plugin inconsistency (#11043)
* fix(ToolPermissionRequestCard): simplify button rendering by removing suggestion handling

*  feat: add CachedPluginsDataSchema for plugin cache file

- Add Zod schema for .claude/plugins.json cache file format
- Schema includes version, lastUpdated timestamp, and plugins array
- Reuses existing InstalledPluginSchema for type safety
- Cache will store metadata for all installed plugins

*  feat: add cache management methods to PluginService

- Add readCacheFile() to read .claude/plugins.json
- Add writeCacheFile() for atomic cache writes (temp + rename)
- Add rebuildCache() to scan filesystem and rebuild cache
- Add listInstalledFromCache() to load plugins from cache with fallback
- Add updateCache() helper for transactional cache updates
- All methods handle missing/corrupt cache gracefully
- Cache auto-regenerates from filesystem if needed

*  feat: integrate cache loading in AgentService.getAgent()

- Add installed_plugins field to GetAgentResponseSchema
- Load plugins from cache via PluginService.listInstalledFromCache()
- Gracefully handle errors by returning empty array
- Use loggerService for error logging

* 🐛 fix: break circular dependency causing infinite loop in cache methods

- Change cache method signatures from agentId to workdir parameter
- Update listInstalledFromCache(workdir) to accept workdir directly
- Update rebuildCache(workdir) to accept workdir directly
- Update updateCache(workdir, updater) to accept workdir directly
- AgentService.getAgent() now passes accessible_paths[0] to cache methods
- Removes AgentService.getAgent() calls from PluginService methods
- Fixes infinite recursion bug where methods called each other endlessly

Breaking the circular dependency:
BEFORE: AgentService.getAgent() → PluginService.listInstalledFromCache(id)
        → AgentService.getAgent(id) [INFINITE LOOP]
AFTER:  AgentService.getAgent() → PluginService.listInstalledFromCache(workdir)
        [NO MORE RECURSION]

* 🐛 fix: update listInstalled() to use agent.installed_plugins

- Change from agent.configuration.installed_plugins (old DB location)
- To agent.installed_plugins (new top-level field from cache)
- Simplify validation logic to use existing plugin structure
- Fixes UI not showing installed plugins correctly

This was causing the UI to show empty plugin lists even though plugins
were correctly loaded in the cache by AgentService.getAgent().

* ♻️ refactor: remove unused updateCache helper

* ♻️ refactor: centralize plugin directory helpers

* feat: Implement Plugin Management System

- Added PluginCacheStore for managing plugin metadata and caching.
- Introduced PluginInstaller for handling installation and uninstallation of plugins.
- Created PluginService to manage plugin lifecycle, including installation, uninstallation, and listing of available plugins.
- Enhanced AgentService to integrate with PluginService for loading installed plugins.
- Implemented validation and sanitization for plugin file names and paths to prevent security issues.
- Added support for skills as a new plugin type, including installation and management.
- Introduced caching mechanism for available plugins to improve performance.

* ♻️ refactor: simplify PluginInstaller and PluginService by removing agent dependency and updating plugin handling
2025-10-31 14:30:50 +08:00
亢奋猫
f8a599322f feat(useAppInit): implement automatic update checks with interval sup… (#11063)
feat(useAppInit): implement automatic update checks with interval support

- Added a function to check for updates, which is called initially and set to run every 6 hours if the app is packaged and auto-update is enabled.
- Refactored the initial update check to utilize the new function for better code organization and clarity.
2025-10-31 13:35:27 +08:00
defi-failure
aa810a7ead fix: notify renderer when api server ready (#11049)
* fix: notify renderer when api server ready

* chore: minor comment update

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

* fix: minor ui change to reflect server loading state

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-31 12:13:59 +08:00
Pleasure1234
b586e1796e fix: sort grouped items by saved tags order from Redux (#11065)
Updated useUnifiedGrouping to sort grouped items by the tags order saved in the Redux store, falling back to untagged first. This improves consistency with user-defined tag ordering.
2025-10-31 11:21:10 +08:00
fullex
23f7b39753 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-10-31 11:12:49 +08:00
George·Dong
fa2ec69fa9 fix(SettingsTab): Context slider inconsistent (#10943)
* fix(i18n): standardize "max" translation to indicate unlimited

* feat(SettingsTab): add current context

* feat(settings): show proper "max" label for context count

* fix(settings): simplify contextCount value expression

* feat(settings): make context count editable with number input
2025-10-30 20:15:35 +08:00
MyPrototypeWhat
fe188ba8fb feat: enhance design token management and documentation
- Added new design token files including design-tokens.css and theme.css to standardize styling across the UI.
- Introduced a conversion log (CONVERSION_LOG.md) detailing the migration from todocss.css to design-tokens.css, including variable updates and deprecations.
- Updated package.json to include new CSS files for easier imports.
- Enhanced README.md to provide clear guidelines on the design reference and usage of design tokens.
- Improved globals.css to integrate with the new design token structure and ensure consistency in styling.
2025-10-30 19:40:19 +08:00
SuYao
dd8690b592 feat: 添加路由懒加载组件以优化页面加载性能 (#11042) 2025-10-30 16:41:07 +08:00
MyPrototypeWhat
09e6b9741e fix: update GlobTool to count lines instead of files in output (#11036) 2025-10-30 16:14:04 +08:00
ABucket
0767952a6f docs: fix invalid link in the contributing guide (#11038)
docs: fix invalid link
2025-10-29 22:28:38 +08:00
MyPrototypeWhat
72299f833a feat(ReadTool): add function to remove <system-reminder> tags (#11034)
feat(ReadTool): add function to remove <system-reminder> tags from output text

- Introduced `removeSystemReminderTags` function to clean output by removing <system-reminder> tags and their content.
- Updated output processing logic to apply this function for both array and string output types, ensuring consistent formatting.
2025-10-29 22:24:44 +08:00
MyPrototypeWhat
7badaf02b9 fix(TodoWriteTool): remove output rendering from TodoWriteTool component (#11035)
* fix: remove output rendering from TodoWriteTool component

* refactor: remove output parameter from TodoWriteTool component
2025-10-29 20:37:54 +08:00
MyPrototypeWhat
cf008ca22e feat: update migration status documentation for Cherry Studio UI
- Expanded the migration status document to outline the comprehensive plan for transitioning from antd + styled-components to shadcn/ui + Tailwind CSS.
- Introduced detailed migration strategies, principles, and component classification guidelines.
- Added extraction criteria and migration steps to ensure a structured approach to component migration and optimization.
- Emphasized collaboration with UI designers for maintaining design consistency throughout the migration process.
2025-10-29 18:06:30 +08:00
MyPrototypeWhat
851ff8992f style: format color variables in todocss.css for improved readability
- Reformatted color variable definitions in todocss.css to enhance readability by breaking long lines into multiple lines.
- Ensured consistency in the formatting of HSLA values across the file.
2025-10-29 16:56:31 +08:00
MyPrototypeWhat
91f9088436 feat: add design system documentation and todocss.css file
- Introduced a comprehensive design system document outlining integration strategies for Tailwind CSS v4, usage guidelines, and UI library balance strategies.
- Added todocss.css file containing typography, spacing, sizing, and color variables for the design system.
- Established naming conventions and core transformation rules for design tokens to enhance consistency and usability across the UI components.
2025-10-29 16:52:05 +08:00
fullex
c971daf23c Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-10-29 16:43:40 +08:00
fullex
0c7cee2700 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-10-29 16:37:54 +08:00
defi-failure
dfbfc2869c fix: use session model when sending messages (#11028) 2025-10-29 16:32:04 +08:00
Phantom
1575e97168 fix: approved tools (#11025)
* refactor(agent): move permission mode types and constants to config

Move PermissionModeCard type definition to types/agent.ts and relocate permissionModeCards constant from constants/permissionModes.ts to config/agent.ts for better organization and maintainability

* refactor(AgentSettings): simplify state management in ToolingSettings

remove redundant state for selectedMode and derive it from configuration
consolidate permission mode constants import path

* docs(AgentSettings): add jsdoc for computeModeDefaults function

* refactor(AgentSettings): simplify tooling state management with useMemo

remove redundant state for autoToolIds and compute it directly using useMemo

* refactor(AgentSettings): simplify tool approval state management

- Replace useState with useMemo for approvedToolIds to prevent unnecessary state updates
- Remove redundant state transitions and simplify toggle logic
- Ensure consistent tool filtering and merging with defaults

* refactor(AgentSettings): replace useState with useMemo for configuration state

Optimize performance by memoizing agent configuration state to prevent unnecessary re-renders

* perf(AgentSettings): optimize permission_mode computation with useMemo

Prevent unnecessary recalculations of permission_mode by memoizing the value

* refactor(AgentSettings): simplify MCP selection logic and remove unused imports

Remove useEffect for MCP state synchronization and directly use memoized value
Clean up unused imports and simplify toggle handler logic

* refactor: remove unused useAgentClient hook from ToolingSettings
2025-10-29 16:21:29 +08:00
SuYao
e0a2ed0481 Provider Config & anthropic-web-fetch (#10808)
* fix: update AI SDK dependencies to latest versions

* feat: Update provider configurations and API handling

- Refactor provider configuration to support new API types and enhance API host formatting.
- Introduce new utility functions for handling API versions and formatting Azure OpenAI hosts.
- Update system models to include new capabilities and adjust provider types for CherryIN and VertexAI.
- Enhance provider settings UI to accommodate new API types and improve user experience.
- Implement migration logic for provider type updates and default API host settings.
- Update translations for API host configuration tips across multiple languages.
- Fix various type checks and utility functions to ensure compatibility with new provider types.

* fix: update unsupported API version providers and add longcat to compatible provider IDs

* fix: 移除不再使用的 Azure OpenAI API 版本参数,优化 API 主机格式化逻辑
feat: 在选择器组件中添加样式属性,增强可定制性
feat: 更新提供者设置,支持动态选择 API 主机字段

* refactor: 优化测试用例

* 修复: 更新工具调用处理器以支持新的工具调用类型

* feat: 添加TODO注释以改进基于AI SDK的供应商内置工具展示和类型安全处理

* feat: 添加对Google SDK的支持,更新流式参数构建逻辑以包含Google工具的上下文

* feat: 更新web搜索模型判断逻辑,使用SystemProviderIds常量替代硬编码字符串

* feat: 添加对@renderer/store的mock以支持测试环境

* feat: 添加API主机地址验证功能,更新相关逻辑以支持端点提取

* fix: i18n

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

* Apply suggestion from @EurFelux

Co-authored-by: Phantom <eurfelux@gmail.com>

* Apply suggestion from @EurFelux

Co-authored-by: Phantom <eurfelux@gmail.com>

* Apply suggestion from @EurFelux

Co-authored-by: Phantom <eurfelux@gmail.com>

* refactor: Simplify provider type migration logic and enhance API version validation

* fix: Correct variable name from configedApiHost to configuredApiHost for consistency

* fix: Update package.json to remove deprecated @ai-sdk/google version and streamline @ai-sdk/openai versioning

* fix: 更新 hasAPIVersion 函数中的正则表达式以更准确地匹配 API 版本路径

* fix(api): 简化 validateApiHost 函数逻辑以始终返回 true
fix(yarn): 更新 @ai-sdk/openai 版本至 2.0.53 并添加依赖项

* fix(api): 修正 validateApiHost 函数在使用哈希后缀时的验证逻辑

---------

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Phantom <eurfelux@gmail.com>
2025-10-29 14:47:21 +08:00
fullex
3e9d9f16d6 fix: test 2025-10-29 14:45:55 +08:00
fullex
f3a279d8de Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2025-10-29 14:28:03 +08:00
LiuVaayne
5790c12011 Feat: Enhanced Tool Permission System with Real-time Approvals #10738 (#10743)
* ⬆️ chore: upgrade claude agent sdk to 0.1.15

*  feat: add initial tool permission approval system

- Add promptForToolApproval function for real-time tool approval UI
- Integrate canUseTool callback into ClaudeCodeService
- Create tool-permissions.ts module for permission handling
- Set foundation for enhanced tool permission system #10738

This provides the basic infrastructure for displaying tool approval
prompts and getting user consent before agents execute potentially
dangerous operations.

* restore to main for

restore to main for

*  feat: implement agent tool permission request system

Add comprehensive tool permission management for Claude Code agents with:
- IPC channels for bidirectional permission requests/responses between main and renderer
- Permission request queue with timeout (30s), abort signal handling, and auto-cleanup
- Auto-approval system via CHERRY_AUTO_ALLOW_TOOLS env var and default allow-list (Read, Glob, Grep)
- New ToolPermissionRequestCard UI component for user approval with input preview
- Redux store (toolPermissions) for tracking pending/resolved permission requests
- User input stream architecture allowing dynamic user messages during agent execution

Key changes:
- packages/shared/IpcChannel.ts: Add AgentToolPermission_* channels
- src/main/services/agents/services/claudecode/: Refactor canUseTool with permission prompts
- src/renderer/src/store/toolPermissions.ts: New Redux slice for permission state
- src/renderer/src/pages/home/Messages/Tools/ToolPermissionRequestCard.tsx: Interactive approval UI

* refactor: simplify ToolPermissionRequestCard by removing unused imports and suggestion handling logic

* feat: add i18n

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

---------

Co-authored-by: dev <verc20.dev@proton.me>
Co-authored-by: GitHub Action <action@github.com>
2025-10-29 13:37:32 +08:00
LiuVaayne
352ecbc506 feat: add plugin management system for Claude Agent (agents, commands, skills) (#10854)
*  feat: add claude-code-templates via git submodule with build-time copy

- Add git submodule for davila7/claude-code-templates
- Create scripts/copy-templates.js to copy components at build time
- Update package.json build script to include template copying
- Add resources/data/components/ to .gitignore (generated files)

Templates are now automatically synced from external repo to resources/data/components/
during build process, avoiding manual file copying.

To update templates: git submodule update --remote --merge

* fix: update target directory for copying Claude Code templates

*  feat: merge Anthropics skills into template sync

* 📝 docs: add agent plugins management implementation spec

Add comprehensive implementation plan for plugin management feature:
- Security validation and transactional operations
- Plugin browsing, installation, and management UI
- IPC handlers and PluginService architecture
- Metadata caching and database integration

*  feat: add plugin management backend infrastructure

Backend implementation for Claude Code plugin management:

- Add PluginService with security validation and caching
- Create IPC handlers for plugin operations (list, install, uninstall)
- Add markdown parser with safe YAML frontmatter parsing
- Extend AgentConfiguration schema with installed_plugins field
- Update preload bridge to expose plugin API to renderer
- Add plugin types (PluginMetadata, PluginError, PluginResult)

Features:
- Transactional install/uninstall with rollback
- Path traversal prevention and file validation
- 5-minute plugin list caching for performance
- SHA-256 content hashing for integrity checks
- Duplicate plugin handling (auto-replace)

Dependencies added:
- gray-matter: Markdown frontmatter parsing
- js-yaml: Safe YAML parsing with FAILSAFE_SCHEMA

*  feat: add plugin management UI and integration

Complete frontend implementation for Claude Code plugin management:

**React Hooks:**
- useAvailablePlugins: Fetch and cache available plugins
- useInstalledPlugins: List installed plugins with refresh
- usePluginActions: Install/uninstall with loading states

**UI Components (HeroUI):**
- PluginCard: Display plugin with install/uninstall actions
- CategoryFilter: Multi-select chip-based category filter
- InstalledPluginsList: Table view with uninstall confirmation
- PluginBrowser: Search, filter, pagination, responsive grid
- PluginSettings: Main container with Available/Installed tabs

**Integration:**
- Added "Plugins" tab to AgentSettingsPopup
- Full i18n support (English, Simplified Chinese, Traditional Chinese)
- Toast notifications for success/error states
- Loading skeletons and empty states

**Features:**
- Search plugins by name/description
- Filter by category and type (agents/commands)
- Pagination (12 items per page)
- Install/uninstall with confirmation dialogs
- Real-time plugin list updates
- Responsive grid layout (1-3 columns)

All code formatted with Biome and follows existing patterns.

* 🐛 fix: add missing plugin i18n keys at root level

Add plugin translation keys at root 'plugins.*' level to match component usage:
- Search and filter UI strings
- Pluralization support for result counts
- Empty state messages
- Action button labels
- Confirmation dialog text

Translations added for all three locales (en-US, zh-CN, zh-TW).

* 🐛 fix: use getResourcePath() utility for plugin directory resolution

Replace manual path calculation with getResourcePath() utility which correctly
handles both development and production environments. This fixes the issue where
plugins were not loading because __dirname was resolving to the wrong location.

Fixes:
- Plugins now load correctly in development mode
- Path resolution consistent with other resource loading in the app
- Removed unused 'app' import from electron

* 🎨 fix: improve plugin UI scrolling and category filter layout

Fixes two UI issues:

1. Enable scrolling for plugin list:
   - Changed overflow-hidden to overflow-y-auto on tab containers
   - Plugin grid now scrollable when content exceeds viewport

2. Make category filter more compact:
   - Added max-h-24 (96px) height limit to category chip container
   - Enabled vertical scrolling for category chips
   - Prevents category filter from taking too much vertical space

UI improvements enhance usability when browsing large plugin collections.

* 🎨 fix: ensure both agent and command badges have visible backgrounds

Changed Chip variant from 'flat' to 'solid' for plugin type badges.
This ensures both agent (primary) and command (secondary) badges display
with consistent, visible background colors instead of command badges
appearing as text-only.

*  feat: add plugin detail modal for viewing full plugin information

Add modal to display complete plugin details when clicking on a card:

Features:
- Click any plugin card to view full details in a modal
- Shows complete description (not truncated)
- Displays all metadata: version, author, tools, allowed_tools, tags
- Shows file info: filename, size, source path, install date
- Install/uninstall actions available in modal
- Hover effect on cards to indicate clickability
- Button clicks don't trigger card click (event.stopPropagation)

Components:
- New PluginDetailModal component with scrollable content
- Updated PluginCard to be clickable (isPressable)
- Updated PluginBrowser to manage modal state

UI improvements provide better plugin exploration and decision-making.

* 🐛 fix: render plugin detail modal above agent settings modal

Use React portal to render PluginDetailModal directly to document.body,
ensuring it appears above the agent settings modal instead of being
blocked by it.

Changes:
- Import createPortal from react-dom
- Wrap modal content in createPortal(modalContent, document.body)
- Add z-[9999] to modal wrapper for proper layering

Fixes modal visibility issue where plugin details were hidden behind
the parent agent settings modal.

*  feat: add plugin content viewing and editing in detail modal

- Added IPC channels for reading and writing plugin content
- Implemented readContent() and writeContent() methods in PluginService
- Added IPC handlers for content operations with proper error handling
- Exposed plugin content API through preload bridge
- Updated PluginDetailModal to fetch and display markdown content
- Added edit mode with textarea for modifying plugin content
- Implemented save/cancel functionality with optimistic UI updates
- Added agentId prop to component chain for write operations
- Updated AgentConfigurationSchema to include all plugin metadata fields
- Moved plugin types to shared @types for cross-process access
- Added validation and security checks for content read/write
- Updated content hash in DB after successful edits

* 🐛 fix: change event handler from onPress to onClick for uninstall and install buttons

* 📝 docs: update AI Assistant Guide to clarify proposal and commit guidelines

* 📝 docs: add skills support extension spec for agent plugins management

*  feat: add secure file operation utilities for skills plugin system

- Implement copyDirectoryRecursive() with security protections
- Implement deleteDirectoryRecursive() with path validation
- Implement getDirectorySize() for folder size calculation
- Add path traversal protection using isPathInside()
- Handle symlinks securely to prevent attacks
- Add recursion depth limits to prevent stack overflow
- Preserve file permissions during copy
- Handle race conditions and missing files gracefully
- Skip special files (pipes, sockets, devices)

Security features:
- Path validation against allowedBasePath boundary
- Symlink detection and skip to prevent circular loops
- Input validation for null/empty/relative paths
- Comprehensive error handling and logging

Updated spec status to "In Progress" and added implementation progress checklist.

*  feat: add skill type support and skill metadata parsing

Type System Updates (plugin.ts):
- Add PluginType export for 'agent' | 'command' | 'skill'
- Update PluginMetadataSchema to include 'skill' in type enum
- Update InstalledPluginSchema to support skill type
- Update all option interfaces to support skill type
- Add skills array to ListAvailablePluginsResult
- Document filename semantics differences between types

Markdown Parser Updates (markdownParser.ts):
- Implement parseSkillMetadata() function for SKILL.md parsing
- Add comprehensive input validation (absolute path check)
- Add robust error handling with specific PluginErrors
- Add try-catch around file operations and YAML parsing
- Add type validation for frontmatter data fields
- Add proper logging using loggerService
- Handle getDirectorySize() failures gracefully
- Document hash scope decision (SKILL.md only vs entire folder)
- Use FAILSAFE_SCHEMA for safe YAML parsing

Security improvements:
- Path validation to ensure absolute paths
- Differentiate ENOENT from permission errors
- Type validation for all frontmatter fields
- Safe YAML parsing to prevent deserialization attacks

Updated spec progress tracking.

*  feat: implement complete skill support in PluginService

Core Infrastructure:
- Add imports for parseSkillMetadata and file operation utilities
- Add PluginType to imports for type-safe handling

Skill-Specific Methods:
- sanitizeFolderName() - validates folder names (no dots allowed)
- scanSkillDirectory() - scans skills/ for skill folders
- installSkill() - copies folders with transaction/rollback
- uninstallSkill() - removes folders with transaction/rollback

Updated Methods for Skills Support:
- listAvailable() - now scans and returns skills array
- install() - branches on type to handle skills vs files
- uninstall() - branches on type for skill/file handling
- ensureClaudeDirectory() - handles 'skills' subdirectory
- listInstalled() - validates skill folders on filesystem
- writeContent() - updated signature to accept PluginType

Key Implementation Details:
- Skills use folder names WITHOUT extensions
- Agents/commands use filenames WITH .md extension
- Different sanitization rules for folders vs files
- Transaction pattern with rollback for all operations
- Comprehensive logging and error handling
- Maintains backward compatibility with existing code

Updated spec progress tracking.

*  feat: add skill support to frontend hooks and UI components

Frontend Hooks (usePlugins.ts):
- Add skills state to useAvailablePlugins hook
- Return skills array in hook result
- Update install() to accept 'skill' type
- Update uninstall() to accept 'skill' type

UI Components:
- PluginCard: Add 'skill' type badge with success color
- PluginBrowser: Add skills prop and include in plugin list
- PluginBrowser: Update type definitions to include 'skill'
- PluginBrowser: Include skills in tab filtering

Complete frontend integration for skills plugin type.
Updated spec progress tracking.

* ♻️ refactor: remove unused variable in installSkill method

* 📝 docs: mark implementation as complete with summary

Implementation Status: COMPLETE (11/12 tasks)

Completed:
-  File operation utilities with security protections
-  Skill metadata parsing with validation
-  Plugin type system updated to include 'skill'
-  PluginService skill methods (scan, install, uninstall)
-  PluginService updated for skill support
-  IPC handlers (no changes needed - already generic)
-  Frontend hooks updated for skills
-  UI components updated (PluginCard, PluginBrowser)
-  Build check passed with lint fixes

Deferred (non-blocking):
- ⏸️ Session integration - requires further investigation
  into session handler location and implementation

The core skills plugin system is fully implemented and functional.
Skills can be browsed, installed, and uninstalled through the UI.
All security requirements met with path validation and transaction
rollback. Code passes lint checks and follows project patterns.

* 🐛 fix: pass skills prop to PluginBrowser component

Fixed "skills is not iterable" error by:
- Destructuring skills from useAvailablePlugins hook
- Updating type annotations to include 'skill' type
- Passing skills prop to PluginBrowser component

This completes the missing UI wiring for skills support.

*  feat: add Skills tab to plugin browser

Added missing Skills tab to PluginBrowser component:
- Added Skills tab to type tabs
- Added translations for skills in all locales (en-us, zh-cn, zh-tw)
  - English: "Skills"
  - Simplified Chinese: "技能"
  - Traditional Chinese: "技能"

This completes the UI integration for the skills plugin type.

*  feat: add 'skill' type to AgentConfiguration and GetAgentSessionResponse schemas

* ⬆️ chore: upgrade @anthropic-ai/claude-agent-sdk to v0.1.25 with patch

- Updated from v0.1.1 to v0.1.25
- Applied fork/IPC patch to new version
- Removed old patch file
- All tests passing

* 🐛 fix: resolve linting and TypeScript type errors in build check

- Add external/** and resources/data/claude-code-plugins/** to lint ignore patterns
  to exclude git submodules and plugin templates from linting
- Fix TypeScript error handling in IPC handlers by properly typing caught errors
- Fix AgentConfiguration type mismatches by providing default values for
  permission_mode and max_turns when spreading configuration
- Replace control character regex with String.fromCharCode() to avoid ESLint
  no-control-regex rule in sanitization functions
- Fix markdownParser yaml.load return type by adding type assertion
- Add getPluginErrorMessage helper to properly extract error messages from
  PluginError discriminated union types

Main process TypeScript errors: Fixed (0 errors)
Linting errors: Fixed (0 errors from 4397)
Remaining: 4 renderer TypeScript errors in settings components

* ♻️ refactor: improve plugin error handling and reorganize i18n structure

* ⬆️ chore: update @anthropic-ai/claude-agent-sdk to include patch and additional dependencies

* 🗑️ chore: remove unused Claude code plugins and related configurations

- Deleted `.gitmodules` and associated submodules for `claude-code-templates` and `anthropics-skills`.
- Updated `.gitignore`, `.oxlintrc.json`, and `eslint.config.mjs` to exclude `claude-code-plugins`.
- Modified `package.json` to remove the build script dependency on copying templates.
- Adjusted `PluginService.ts` to handle plugin paths without relying on removed resources.

* format code

* delete

* delete

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

*  feat: enhance PluginService and markdownParser with recursive skill directory search

- Added `findAllSkillDirectories` function to recursively locate directories containing `SKILL.md`.
- Updated `scanSkillDirectory` method in `PluginService` to utilize the new recursive search.
- Modified `PluginDetailModal` to append `/SKILL.md` to the source path for skill plugins.

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

* remove specs

* update claude code plugins files

---------

Co-authored-by: suyao <sy20010504@gmail.com>
Co-authored-by: beyondkmp <beyondkmp@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
2025-10-29 13:33:11 +08:00
George·Dong
fc4f30feab fix: update Dashscope Anthropic API host and migrate old configs (#10973)
* fix: update Dashscope Anthropic API host and migrate old configs

* fix(migration): remove obsolete dashscope rewrite

* fix(migrate): overwrite Anthropic API host for dashscope provider
2025-10-29 09:20:19 +08:00
Carlton
888a183328 feat(knowledge, preprocess): Add OpenMinerU preprocessor, knowledge base supports using open-source version of MinerU to process documents (#10992)
* feat(knowledge): 为文档处理增加open-mineru的支持

* 移除OpenMineruPreprocessProvider多余的apiKey处理

* Add preprocessProviders migrator for open-mineru

* Remove invalid code from OpenMineruPreprocessProvider

* fix property '"open-mineru"' is missing in PREPROCESS_PROVIDER_CONFIG

* refactor(preprocess): improve OpenMinerU error handling and file cleanup
2025-10-29 09:19:18 +08:00
scientia
9a01e092f6 feat: allow new-topic bindkey to create new session for agent as well (#10862)
* fix: allow new-topic shortcut to create agent sessions

* revert: restore ProxyManager.ts

* fix: make agent session shortcut sidebar-independent

* refactor: centralize default session creation

* feat: add new session button to agent inputbar

* fix: encapsulate agent session creation state

* refactor: remove redundant useMemo in useCreateDefaultSession

The useMemo wrapper around the return object was unnecessary because:
- createDefaultSession is already memoized via useCallback
- creatingSession is a primitive boolean that doesn't need memoization
- The object gets recreated on every creatingSession change anyway

This simplifies the code and removes unnecessary overhead.

---------

Co-authored-by: wangdenghui <wangdenghui@xiaomi.com>
2025-10-28 22:59:44 +08:00
George·Dong
5986800c9d chore(ci): exempt all milestones and assignee from staling (#11008) 2025-10-28 19:20:05 +08:00
槑囿脑袋
56d68276e1 fix(knowledge): force choose knowledge aisdk error (#11006)
fix: aisdk error
2025-10-28 16:37:58 +08:00
Copilot
29c1173365 Fix Qwen3 thinking mode control for Ollama using aiCore middleware (#10947)
* Initial plan

* Fix Qwen3 thinking mode control for Ollama by using reasoning_effort instead of qwenThinkMode

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>

* Refactor: Move Qwen thinking mode control from legacy to aiCore middleware

- Revert changes to legacy OpenAIApiClient.ts
- Create new qwenThinkingMiddleware for handling /think and /no_think suffixes
- Update AiSdkMiddlewareBuilder to add assistant field and apply Qwen middleware
- Middleware automatically handles Qwen models on Ollama, LM Studio, and NVIDIA providers
- This follows the modern aiCore architecture instead of deprecated legacy approach

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>

* Fix: Explicitly pass assistant field to buildAiSdkMiddlewares

Ensure that the assistant field from ModernAiProviderConfig is explicitly passed
to buildAiSdkMiddlewares so that Qwen thinking middleware can access
assistant.settings.reasoning_effort correctly.

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>

* Fix: Remove unnecessary whitespace in processPostsuffixQwen3Model tests

* Refactor: Simplify user message suffix handling in qwenThinkingMiddleware

* Refactor: Remove processPostsuffixQwen3Model tests to streamline ModelMessageService tests

* refactor: remove logger and debug statement from qwenThinkingMiddleware

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>
Co-authored-by: suyao <sy20010504@gmail.com>
2025-10-28 14:26:54 +08:00
Jake Jia
c7ceb3035d fix: align and unify LocalBackupManager footer layout (#10985)
* fix: align and unify LocalBackupManager footer layout

- Use Space component to wrap footer buttons, consistent with S3BackupManager
- Optimize delete button i18n text by using count parameter instead of hardcoded concatenation

* fix: fix the i18n issue in the  delete button text
2025-10-28 13:26:53 +08:00
Phantom
7bcae6fba2 fix(Navbar): adjust min-height calculation for fullscreen mode on Mac (#10990)
Ensure the navbar height is correctly calculated when toggling fullscreen mode on macOS by considering the $isFullScreen prop
2025-10-28 10:29:28 +08:00
615 changed files with 35752 additions and 14875 deletions

View File

@@ -1,4 +1,4 @@
name: 🐛 Bug Report (English)
name: 🐛 Bug Report
description: Create a report to help us improve
title: '[Bug]: '
labels: ['BUG']

View File

@@ -1,4 +1,4 @@
name: 💡 Feature Request (English)
name: 💡 Feature Request
description: Suggest an idea for this project
title: '[Feature]: '
labels: ['feature']

View File

@@ -1,4 +1,4 @@
name: 🤔 Other Questions (English)
name: 🤔 Other Questions
description: Submit questions that don't fit into bug reports or feature requests
title: '[Other]: '
body:

View File

@@ -1,4 +1,4 @@
name: Auto I18N
name: Auto I18N Weekly
env:
TRANSLATION_API_KEY: ${{ secrets.TRANSLATE_API_KEY }}
@@ -7,14 +7,15 @@ env:
TRANSLATION_BASE_LOCALE: ${{ vars.AUTO_I18N_BASE_LOCALE || 'en-us'}}
on:
pull_request:
types: [opened, synchronize, reopened]
schedule:
# Runs at 00:00 UTC every Sunday.
# This corresponds to 08:00 AM UTC+8 (Beijing time) every Sunday.
- cron: "0 0 * * 0"
workflow_dispatch:
jobs:
auto-i18n:
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == 'CherryHQ/cherry-studio'
name: Auto I18N
permissions:
contents: write
@@ -24,45 +25,69 @@ jobs:
- name: 🐈‍⬛ Checkout
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
- name: 📦 Setting Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20
package-manager-cache: false
node-version: 22
- name: 📦 Install dependencies in isolated directory
- name: 📦 Install corepack
run: corepack enable && corepack prepare yarn@4.9.1 --activate
- name: 📂 Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- name: 💾 Cache yarn dependencies
uses: actions/cache@v4
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
node_modules
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: 📦 Install dependencies
run: |
# 在临时目录安装依赖
mkdir -p /tmp/translation-deps
cd /tmp/translation-deps
echo '{"dependencies": {"@cherrystudio/openai": "^6.5.0", "cli-progress": "^3.12.0", "tsx": "^4.20.3", "@biomejs/biome": "2.2.4"}}' > package.json
npm install --no-package-lock
# 设置 NODE_PATH 让项目能找到这些依赖
echo "NODE_PATH=/tmp/translation-deps/node_modules" >> $GITHUB_ENV
yarn install
- name: 🏃‍♀️ Translate
run: npx tsx scripts/sync-i18n.ts && npx tsx scripts/auto-translate-i18n.ts
run: yarn sync:i18n && yarn auto:i18n
- name: 🔍 Format
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/
run: yarn format
- name: 🔄 Commit changes
- name: 🔍 Check for changes
id: git_status
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
# Check if there are any uncommitted changes
git reset -- package.json yarn.lock # 不提交 package.json 和 yarn.lock 的更改
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "fix(i18n): Auto update translations for PR #${{ github.event.pull_request.number }}"
fi
git diff --exit-code --quiet || echo "::set-output name=has_changes::true"
git status --porcelain
- name: 🚀 Push changes
uses: ad-m/github-push-action@master
- name: 📅 Set current date for PR title
id: set_date
run: echo "CURRENT_DATE=$(date +'%b %d, %Y')" >> $GITHUB_ENV # e.g., "Jun 06, 2024"
- name: 🚀 Create Pull Request if changes exist
if: steps.git_status.outputs.has_changes == 'true'
uses: peter-evans/create-pull-request@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.event.pull_request.head.ref }}
token: ${{ secrets.GITHUB_TOKEN }} # Use the built-in GITHUB_TOKEN for bot actions
commit-message: "feat(bot): Weekly automated script run"
title: "🤖 Weekly Automated Update: ${{ env.CURRENT_DATE }}"
body: |
This PR includes changes generated by the weekly auto i18n.
Review the changes before merging.
---
_Generated by the automated weekly workflow_
branch: "auto-i18n-weekly-${{ github.run_id }}" # Unique branch name
base: "main" # Or 'develop', set your base branch
delete-branch: true # Delete the branch after merging or closing the PR
- name: 📢 Notify if no changes
if: steps.git_status.outputs.has_changes != 'true'
run: echo "Bot script ran, but no changes were detected. No PR created."

View File

@@ -5,7 +5,7 @@ on:
types: [opened]
schedule:
# Run every day at 8:30 Beijing Time (00:30 UTC)
- cron: '30 0 * * *'
- cron: "30 0 * * *"
workflow_dispatch:
jobs:
@@ -54,9 +54,9 @@ jobs:
- name: Setup Node.js
if: steps.check_time.outputs.should_delay == 'false'
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: '20'
node-version: 22
- name: Process issue with Claude
if: steps.check_time.outputs.should_delay == 'false'
@@ -121,9 +121,9 @@ jobs:
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: '20'
node-version: 22
- name: Process pending issues with Claude
uses: anthropics/claude-code-action@main

View File

@@ -21,7 +21,7 @@ jobs:
contents: none
steps:
- name: Close needs-more-info issues
uses: actions/stale@v9
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
only-labels: 'needs-more-info'
@@ -29,8 +29,10 @@ jobs:
days-before-close: 0 # Close immediately after stale
stale-issue-label: 'inactive'
close-issue-label: 'closed:no-response'
exempt-all-milestones: true
exempt-all-assignees: true
stale-issue-message: |
This issue has been labeled as needing more information and has been inactive for ${{ env.daysBeforeStale }} days.
This issue has been labeled as needing more information and has been inactive for ${{ env.daysBeforeStale }} days.
It will be closed now due to lack of additional information.
该问题被标记为"需要更多信息"且已经 ${{ env.daysBeforeStale }} 天没有任何活动,将立即关闭。
@@ -40,12 +42,14 @@ jobs:
days-before-pr-close: -1
- name: Close inactive issues
uses: actions/stale@v9
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: ${{ env.daysBeforeStale }}
days-before-close: ${{ env.daysBeforeClose }}
stale-issue-label: 'inactive'
exempt-all-milestones: true
exempt-all-assignees: true
stale-issue-message: |
This issue has been inactive for a prolonged period and will be closed automatically in ${{ env.daysBeforeClose }} days.
该问题已长时间处于闲置状态,${{ env.daysBeforeClose }} 天后将自动关闭。

View File

@@ -3,7 +3,7 @@ name: Nightly Build
on:
workflow_dispatch:
schedule:
- cron: '0 17 * * *' # 1:00 BJ Time
- cron: "0 17 * * *" # 1:00 BJ Time
permissions:
contents: write
@@ -56,9 +56,9 @@ jobs:
ref: main
- name: Install Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20
node-version: 22
- name: macos-latest dependencies fix
if: matrix.os == 'macos-latest'
@@ -66,7 +66,7 @@ jobs:
brew install python-setuptools
- name: Install corepack
run: corepack enable && corepack prepare yarn@4.6.0 --activate
run: corepack enable && corepack prepare yarn@4.9.1 --activate
- name: Get yarn cache directory path
id: yarn-cache-dir-path
@@ -208,7 +208,7 @@ jobs:
echo "总计: $(find renamed-artifacts -type f | wc -l) 个文件"
- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: cherry-studio-nightly-${{ steps.date.outputs.date }}-${{ matrix.os }}
path: renamed-artifacts/*

View File

@@ -24,12 +24,12 @@ jobs:
uses: actions/checkout@v5
- name: Install Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20
node-version: 22
- name: Install corepack
run: corepack enable && corepack prepare yarn@4.6.0 --activate
run: corepack enable && corepack prepare yarn@4.9.1 --activate
- name: Get yarn cache directory path
id: yarn-cache-dir-path

View File

@@ -4,9 +4,9 @@ on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag (e.g. v1.0.0)'
description: "Release tag (e.g. v1.0.0)"
required: true
default: 'v1.0.0'
default: "v1.0.0"
push:
tags:
- v*.*.*
@@ -47,9 +47,9 @@ jobs:
npm version "$VERSION" --no-git-tag-version --allow-same-version
- name: Install Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20
node-version: 22
- name: macos-latest dependencies fix
if: matrix.os == 'macos-latest'
@@ -57,7 +57,7 @@ jobs:
brew install python-setuptools
- name: Install corepack
run: corepack enable && corepack prepare yarn@4.6.0 --activate
run: corepack enable && corepack prepare yarn@4.9.1 --activate
- name: Get yarn cache directory path
id: yarn-cache-dir-path
@@ -127,5 +127,5 @@ jobs:
allowUpdates: true
makeLatest: false
tag: ${{ steps.get-tag.outputs.tag }}
artifacts: 'dist/*.exe,dist/*.zip,dist/*.dmg,dist/*.AppImage,dist/*.snap,dist/*.deb,dist/*.rpm,dist/*.tar.gz,dist/latest*.yml,dist/rc*.yml,dist/beta*.yml,dist/*.blockmap'
artifacts: "dist/*.exe,dist/*.zip,dist/*.dmg,dist/*.AppImage,dist/*.snap,dist/*.deb,dist/*.rpm,dist/*.tar.gz,dist/latest*.yml,dist/rc*.yml,dist/beta*.yml,dist/*.blockmap"
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -22,7 +22,6 @@
"eslint.config.mjs"
],
"overrides": [
// set different env
{
"env": {
"node": true
@@ -37,8 +36,7 @@
"src/renderer/**/*.{ts,tsx}",
"packages/aiCore/**",
"packages/extension-table-plus/**",
"packages/ui/**",
"resources/js/**"
"packages/ui/**"
]
},
{
@@ -54,76 +52,24 @@
"node": true
},
"files": ["src/preload/**"]
},
{
"files": ["packages/ai-sdk-provider/**"],
"globals": {
"fetch": "readonly"
}
}
],
// We don't use the React plugin here because its behavior differs slightly from that of ESLint's React plugin.
"plugins": ["unicorn", "typescript", "oxc", "import"],
"rules": {
"constructor-super": "error",
"for-direction": "error",
"getter-return": "error",
"no-array-constructor": "off",
// "import/no-cycle": "error", // tons of error, bro
"no-async-promise-executor": "error",
"no-caller": "warn",
"no-case-declarations": "error",
"no-class-assign": "error",
"no-compare-neg-zero": "error",
"no-cond-assign": "error",
"no-const-assign": "error",
"no-constant-binary-expression": "error",
"no-constant-condition": "error",
"no-control-regex": "error",
"no-debugger": "error",
"no-delete-var": "error",
"no-dupe-args": "error",
"no-dupe-class-members": "error",
"no-dupe-else-if": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty": "error",
"no-empty-character-class": "error",
"no-empty-pattern": "error",
"no-empty-static-block": "error",
"no-eval": "warn",
"no-ex-assign": "error",
"no-extra-boolean-cast": "error",
"no-fallthrough": "warn",
"no-func-assign": "error",
"no-global-assign": "error",
"no-import-assign": "error",
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-loss-of-precision": "error",
"no-misleading-character-class": "error",
"no-new-native-nonconstructor": "error",
"no-nonoctal-decimal-escape": "error",
"no-obj-calls": "error",
"no-octal": "error",
"no-prototype-builtins": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-self-assign": "error",
"no-setter-return": "error",
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-this-before-super": "error",
"no-unassigned-vars": "warn",
"no-undef": "error",
"no-unexpected-multiline": "error",
"no-unreachable": "error",
"no-unsafe-finally": "error",
"no-unsafe-negation": "error",
"no-unsafe-optional-chaining": "error",
"no-unused-expressions": "off", // this rule disallow us to use expression to call function, like `condition && fn()`
"no-unused-labels": "error",
"no-unused-private-class-members": "error",
"no-unused-expressions": "off",
"no-unused-vars": ["warn", { "caughtErrors": "none" }],
"no-useless-backreference": "error",
"no-useless-catch": "error",
"no-useless-escape": "error",
"no-useless-rename": "warn",
"no-with": "error",
"oxc/bad-array-method-on-arguments": "warn",
"oxc/bad-char-at-comparison": "warn",
"oxc/bad-comparison-sequence": "warn",
@@ -135,19 +81,17 @@
"oxc/erasing-op": "warn",
"oxc/missing-throw": "warn",
"oxc/number-arg-out-of-range": "warn",
"oxc/only-used-in-recursion": "off", // manually off bacause of existing warning. may turn it on in the future
"oxc/only-used-in-recursion": "off",
"oxc/uninvoked-array-callback": "warn",
"require-yield": "error",
"typescript/await-thenable": "warn",
// "typescript/ban-ts-comment": "error",
"typescript/no-array-constructor": "error",
"typescript/consistent-type-imports": "error",
"typescript/no-array-constructor": "error",
"typescript/no-array-delete": "warn",
"typescript/no-base-to-string": "warn",
"typescript/no-duplicate-enum-values": "error",
"typescript/no-duplicate-type-constituents": "warn",
"typescript/no-empty-object-type": "off",
"typescript/no-explicit-any": "off", // not safe but too many errors
"typescript/no-explicit-any": "off",
"typescript/no-extra-non-null-assertion": "error",
"typescript/no-floating-promises": "warn",
"typescript/no-for-in-array": "warn",
@@ -156,7 +100,7 @@
"typescript/no-misused-new": "error",
"typescript/no-misused-spread": "warn",
"typescript/no-namespace": "error",
"typescript/no-non-null-asserted-optional-chain": "off", // it's off now. but may turn it on.
"typescript/no-non-null-asserted-optional-chain": "off",
"typescript/no-redundant-type-constituents": "warn",
"typescript/no-require-imports": "off",
"typescript/no-this-alias": "error",
@@ -174,20 +118,18 @@
"typescript/triple-slash-reference": "error",
"typescript/unbound-method": "warn",
"unicorn/no-await-in-promise-methods": "warn",
"unicorn/no-empty-file": "off", // manually off bacause of existing warning. may turn it on in the future
"unicorn/no-empty-file": "off",
"unicorn/no-invalid-fetch-options": "warn",
"unicorn/no-invalid-remove-event-listener": "warn",
"unicorn/no-new-array": "off", // manually off bacause of existing warning. may turn it on in the future
"unicorn/no-new-array": "off",
"unicorn/no-single-promise-in-promise-methods": "warn",
"unicorn/no-thenable": "off", // manually off bacause of existing warning. may turn it on in the future
"unicorn/no-thenable": "off",
"unicorn/no-unnecessary-await": "warn",
"unicorn/no-useless-fallback-in-spread": "warn",
"unicorn/no-useless-length-check": "warn",
"unicorn/no-useless-spread": "off", // manually off bacause of existing warning. may turn it on in the future
"unicorn/no-useless-spread": "off",
"unicorn/prefer-set-size": "warn",
"unicorn/prefer-string-starts-ends-with": "warn",
"use-isnan": "error",
"valid-typeof": "error"
"unicorn/prefer-string-starts-ends-with": "warn"
},
"settings": {
"jsdoc": {

View File

@@ -51,6 +51,9 @@
},
"tailwindCSS.classAttributes": [
"className",
"classNames",
"classNames"
],
"tailwindCSS.experimental.classRegex": [
["cva\\(([^;]*)[\\);]", "[`'\"`]([^'\"`;]*)[`'\"`]"]
]
}

View File

@@ -1,13 +0,0 @@
diff --git a/dist/index.mjs b/dist/index.mjs
index 69ab1599c76801dc1167551b6fa283dded123466..f0af43bba7ad1196fe05338817e65b4ebda40955 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -477,7 +477,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
// src/get-model-path.ts
function getModelPath(modelId) {
- return modelId.includes("/") ? modelId : `models/${modelId}`;
+ return modelId?.includes("models/") ? modelId : `models/${modelId}`;
}
// src/google-generative-ai-options.ts

View File

@@ -0,0 +1,26 @@
diff --git a/dist/index.js b/dist/index.js
index ff305b112779b718f21a636a27b1196125a332d9..cf32ff5086d4d9e56f8fe90c98724559083bafc3 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -471,7 +471,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
// src/get-model-path.ts
function getModelPath(modelId) {
- return modelId.includes("/") ? modelId : `models/${modelId}`;
+ return modelId.includes("models/") ? modelId : `models/${modelId}`;
}
// src/google-generative-ai-options.ts
diff --git a/dist/index.mjs b/dist/index.mjs
index 57659290f1cec74878a385626ad75b2a4d5cd3fc..d04e5927ec3725b6ffdb80868bfa1b5a48849537 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -477,7 +477,7 @@ function convertToGoogleGenerativeAIMessages(prompt, options) {
// src/get-model-path.ts
function getModelPath(modelId) {
- return modelId.includes("/") ? modelId : `models/${modelId}`;
+ return modelId.includes("models/") ? modelId : `models/${modelId}`;
}
// src/google-generative-ai-options.ts

View File

@@ -0,0 +1,74 @@
diff --git a/dist/index.js b/dist/index.js
index 992c85ac6656e51c3471af741583533c5a7bf79f..83c05952a07aebb95fc6c62f9ddb8aa96b52ac0d 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -274,6 +274,7 @@ var openaiChatResponseSchema = (0, import_provider_utils3.lazyValidator)(
message: import_v42.z.object({
role: import_v42.z.literal("assistant").nullish(),
content: import_v42.z.string().nullish(),
+ reasoning_content: import_v42.z.string().nullish(),
tool_calls: import_v42.z.array(
import_v42.z.object({
id: import_v42.z.string().nullish(),
@@ -340,6 +341,7 @@ var openaiChatChunkSchema = (0, import_provider_utils3.lazyValidator)(
delta: import_v42.z.object({
role: import_v42.z.enum(["assistant"]).nullish(),
content: import_v42.z.string().nullish(),
+ reasoning_content: import_v42.z.string().nullish(),
tool_calls: import_v42.z.array(
import_v42.z.object({
index: import_v42.z.number(),
@@ -785,6 +787,13 @@ var OpenAIChatLanguageModel = class {
if (text != null && text.length > 0) {
content.push({ type: "text", text });
}
+ const reasoning = choice.message.reasoning_content;
+ if (reasoning != null && reasoning.length > 0) {
+ content.push({
+ type: 'reasoning',
+ text: reasoning
+ });
+ }
for (const toolCall of (_a = choice.message.tool_calls) != null ? _a : []) {
content.push({
type: "tool-call",
@@ -866,6 +875,7 @@ var OpenAIChatLanguageModel = class {
};
let metadataExtracted = false;
let isActiveText = false;
+ let isActiveReasoning = false;
const providerMetadata = { openai: {} };
return {
stream: response.pipeThrough(
@@ -923,6 +933,21 @@ var OpenAIChatLanguageModel = class {
return;
}
const delta = choice.delta;
+ const reasoningContent = delta.reasoning_content;
+ if (reasoningContent) {
+ if (!isActiveReasoning) {
+ controller.enqueue({
+ type: 'reasoning-start',
+ id: 'reasoning-0',
+ });
+ isActiveReasoning = true;
+ }
+ controller.enqueue({
+ type: 'reasoning-delta',
+ id: 'reasoning-0',
+ delta: reasoningContent,
+ });
+ }
if (delta.content != null) {
if (!isActiveText) {
controller.enqueue({ type: "text-start", id: "0" });
@@ -1035,6 +1060,9 @@ var OpenAIChatLanguageModel = class {
}
},
flush(controller) {
+ if (isActiveReasoning) {
+ controller.enqueue({ type: 'reasoning-end', id: 'reasoning-0' });
+ }
if (isActiveText) {
controller.enqueue({ type: "text-end", id: "0" });
}

View File

@@ -1,24 +1,24 @@
diff --git a/sdk.mjs b/sdk.mjs
index 461e9a2ba246778261108a682762ffcf26f7224e..44bd667d9f591969d36a105ba5eb8b478c738dd8 100644
index 8cc6aaf0b25bcdf3c579ec95cde12d419fcb2a71..3b3b8beaea5ad2bbac26a15f792058306d0b059f 100755
--- a/sdk.mjs
+++ b/sdk.mjs
@@ -6215,7 +6215,7 @@ function createAbortController(maxListeners = DEFAULT_MAX_LISTENERS) {
@@ -6213,7 +6213,7 @@ function createAbortController(maxListeners = DEFAULT_MAX_LISTENERS) {
}
// ../src/transport/ProcessTransport.ts
-import { spawn } from "child_process";
+import { fork } from "child_process";
import { createInterface } from "readline";
// ../src/utils/fsOperations.ts
@@ -6473,14 +6473,11 @@ class ProcessTransport {
@@ -6505,14 +6505,11 @@ class ProcessTransport {
const errorMessage = isNativeBinary(pathToClaudeCodeExecutable) ? `Claude Code native binary not found at ${pathToClaudeCodeExecutable}. Please ensure Claude Code is installed via native installer or specify a valid path with options.pathToClaudeCodeExecutable.` : `Claude Code executable not found at ${pathToClaudeCodeExecutable}. Is options.pathToClaudeCodeExecutable set?`;
throw new ReferenceError(errorMessage);
}
- const isNative = isNativeBinary(pathToClaudeCodeExecutable);
- const spawnCommand = isNative ? pathToClaudeCodeExecutable : executable;
- const spawnArgs = isNative ? args : [...executableArgs, pathToClaudeCodeExecutable, ...args];
- this.logForDebugging(isNative ? `Spawning Claude Code native binary: ${pathToClaudeCodeExecutable} ${args.join(" ")}` : `Spawning Claude Code process: ${executable} ${[...executableArgs, pathToClaudeCodeExecutable, ...args].join(" ")}`);
- const spawnArgs = isNative ? [...executableArgs, ...args] : [...executableArgs, pathToClaudeCodeExecutable, ...args];
- this.logForDebugging(isNative ? `Spawning Claude Code native binary: ${spawnCommand} ${spawnArgs.join(" ")}` : `Spawning Claude Code process: ${spawnCommand} ${spawnArgs.join(" ")}`);
+ this.logForDebugging(`Forking Claude Code Node.js process: ${pathToClaudeCodeExecutable} ${args.join(" ")}`);
const stderrMode = env.DEBUG || stderr ? "pipe" : "ignore";
- this.child = spawn(spawnCommand, spawnArgs, {

View File

@@ -1,71 +0,0 @@
diff --git a/dist/utils/tiktoken.cjs b/dist/utils/tiktoken.cjs
index 973b0d0e75aeaf8de579419af31b879b32975413..f23c7caa8b9dc8bd404132725346a4786f6b278b 100644
--- a/dist/utils/tiktoken.cjs
+++ b/dist/utils/tiktoken.cjs
@@ -1,25 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodingForModel = exports.getEncoding = void 0;
-const lite_1 = require("js-tiktoken/lite");
const async_caller_js_1 = require("./async_caller.cjs");
const cache = {};
const caller = /* #__PURE__ */ new async_caller_js_1.AsyncCaller({});
async function getEncoding(encoding) {
- if (!(encoding in cache)) {
- cache[encoding] = caller
- .fetch(`https://tiktoken.pages.dev/js/${encoding}.json`)
- .then((res) => res.json())
- .then((data) => new lite_1.Tiktoken(data))
- .catch((e) => {
- delete cache[encoding];
- throw e;
- });
- }
- return await cache[encoding];
+ throw new Error("TikToken Not implemented");
}
exports.getEncoding = getEncoding;
async function encodingForModel(model) {
- return getEncoding((0, lite_1.getEncodingNameForModel)(model));
+ throw new Error("TikToken Not implemented");
}
exports.encodingForModel = encodingForModel;
diff --git a/dist/utils/tiktoken.js b/dist/utils/tiktoken.js
index 8e41ee6f00f2f9c7fa2c59fa2b2f4297634b97aa..aa5f314a6349ad0d1c5aea8631a56aad099176e0 100644
--- a/dist/utils/tiktoken.js
+++ b/dist/utils/tiktoken.js
@@ -1,20 +1,9 @@
-import { Tiktoken, getEncodingNameForModel, } from "js-tiktoken/lite";
import { AsyncCaller } from "./async_caller.js";
const cache = {};
const caller = /* #__PURE__ */ new AsyncCaller({});
export async function getEncoding(encoding) {
- if (!(encoding in cache)) {
- cache[encoding] = caller
- .fetch(`https://tiktoken.pages.dev/js/${encoding}.json`)
- .then((res) => res.json())
- .then((data) => new Tiktoken(data))
- .catch((e) => {
- delete cache[encoding];
- throw e;
- });
- }
- return await cache[encoding];
+ throw new Error("TikToken Not implemented");
}
export async function encodingForModel(model) {
- return getEncoding(getEncodingNameForModel(model));
+ throw new Error("TikToken Not implemented");
}
diff --git a/package.json b/package.json
index 36072aecf700fca1bc49832a19be832eca726103..90b8922fba1c3d1b26f78477c891b07816d6238a 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,6 @@
"ansi-styles": "^5.0.0",
"camelcase": "6",
"decamelize": "1.2.0",
- "js-tiktoken": "^1.0.12",
"langsmith": ">=0.2.8 <0.4.0",
"mustache": "^4.2.0",
"p-queue": "^6.6.2",

View File

@@ -0,0 +1,68 @@
diff --git a/dist/utils/tiktoken.cjs b/dist/utils/tiktoken.cjs
index c5b41f121d2e3d24c3a4969e31fa1acffdcad3b9..ec724489dcae79ee6c61acf2d4d84bd19daef036 100644
--- a/dist/utils/tiktoken.cjs
+++ b/dist/utils/tiktoken.cjs
@@ -1,6 +1,5 @@
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const require_utils_async_caller = require('./async_caller.cjs');
-const js_tiktoken_lite = require_rolldown_runtime.__toESM(require("js-tiktoken/lite"));
//#region src/utils/tiktoken.ts
var tiktoken_exports = {};
@@ -11,14 +10,10 @@ require_rolldown_runtime.__export(tiktoken_exports, {
const cache = {};
const caller = /* @__PURE__ */ new require_utils_async_caller.AsyncCaller({});
async function getEncoding(encoding) {
- if (!(encoding in cache)) cache[encoding] = caller.fetch(`https://tiktoken.pages.dev/js/${encoding}.json`).then((res) => res.json()).then((data) => new js_tiktoken_lite.Tiktoken(data)).catch((e) => {
- delete cache[encoding];
- throw e;
- });
- return await cache[encoding];
+ throw new Error("TikToken Not implemented");
}
async function encodingForModel(model) {
- return getEncoding((0, js_tiktoken_lite.getEncodingNameForModel)(model));
+ throw new Error("TikToken Not implemented");
}
//#endregion
diff --git a/dist/utils/tiktoken.js b/dist/utils/tiktoken.js
index 641acca03cb92f04a6fa5c9c31f1880ce635572e..707389970ad957aa0ff20ef37fa8dd2875be737c 100644
--- a/dist/utils/tiktoken.js
+++ b/dist/utils/tiktoken.js
@@ -1,6 +1,5 @@
import { __export } from "../_virtual/rolldown_runtime.js";
import { AsyncCaller } from "./async_caller.js";
-import { Tiktoken, getEncodingNameForModel } from "js-tiktoken/lite";
//#region src/utils/tiktoken.ts
var tiktoken_exports = {};
@@ -11,14 +10,10 @@ __export(tiktoken_exports, {
const cache = {};
const caller = /* @__PURE__ */ new AsyncCaller({});
async function getEncoding(encoding) {
- if (!(encoding in cache)) cache[encoding] = caller.fetch(`https://tiktoken.pages.dev/js/${encoding}.json`).then((res) => res.json()).then((data) => new Tiktoken(data)).catch((e) => {
- delete cache[encoding];
- throw e;
- });
- return await cache[encoding];
+ throw new Error("TikToken Not implemented");
}
async function encodingForModel(model) {
- return getEncoding(getEncodingNameForModel(model));
+ throw new Error("TikToken Not implemented");
}
//#endregion
diff --git a/package.json b/package.json
index a24f8fc61de58526051999260f2ebee5f136354b..e885359e8966e7730c51772533ce37e01edb3046 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,6 @@
"ansi-styles": "^5.0.0",
"camelcase": "6",
"decamelize": "1.2.0",
- "js-tiktoken": "^1.0.12",
"langsmith": "^0.3.64",
"mustache": "^4.2.0",
"p-queue": "^6.6.2",

View File

@@ -1,19 +0,0 @@
diff --git a/dist/embeddings.js b/dist/embeddings.js
index 1f8154be3e9c22442a915eb4b85fa6d2a21b0d0c..dc13ef4a30e6c282824a5357bcee9bd0ae222aab 100644
--- a/dist/embeddings.js
+++ b/dist/embeddings.js
@@ -214,10 +214,12 @@ export class OpenAIEmbeddings extends Embeddings {
* @returns Promise that resolves to an embedding for the document.
*/
async embedQuery(text) {
+ const isBaiduCloud = this.clientConfig.baseURL.includes('baidubce.com')
+ const input = this.stripNewLines ? text.replace(/\n/g, ' ') : text
const params = {
model: this.model,
- input: this.stripNewLines ? text.replace(/\n/g, " ") : text,
- };
+ input: isBaiduCloud ? [input] : input
+ }
if (this.dimensions) {
params.dimensions = this.dimensions;
}

View File

@@ -0,0 +1,17 @@
diff --git a/dist/embeddings.js b/dist/embeddings.js
index 6f4b928d3e4717309382e1b5c2e31ab5bc6c5af0..bc79429c88a6d27d4997a2740c4d8ae0707f5991 100644
--- a/dist/embeddings.js
+++ b/dist/embeddings.js
@@ -94,9 +94,11 @@ var OpenAIEmbeddings = class extends Embeddings {
* @returns Promise that resolves to an embedding for the document.
*/
async embedQuery(text) {
+ const isBaiduCloud = this.clientConfig.baseURL.includes('baidubce.com');
+ const input = this.stripNewLines ? text.replace(/\n/g, " ") : text
const params = {
model: this.model,
- input: this.stripNewLines ? text.replace(/\n/g, " ") : text
+ input: isBaiduCloud ? [input] : input
};
if (this.dimensions) params.dimensions = this.dimensions;
if (this.encodingFormat) params.encoding_format = this.encodingFormat;

View File

@@ -10,8 +10,8 @@ This file provides guidance to AI coding assistants when working with code in th
- **Build with HeroUI**: Use HeroUI for every new UI component; never add `antd` or `styled-components`.
- **Log centrally**: Route all logging through `loggerService` with the right context—no `console.log`.
- **Research via subagent**: Lean on `subagent` for external docs, APIs, news, and references.
- **Seek review**: Ask a human developer to review substantial changes before merging.
- **Commit in rhythm**: Keep commits small, conventional, and emoji-tagged.
- **Always propose before executing**: Before making any changes, clearly explain your planned approach and wait for explicit user approval to ensure alignment and prevent unwanted modifications.
- **Write conventional commits**: Commit small, focused changes using Conventional Commit messages (e.g., `feat:`, `fix:`, `refactor:`, `docs:`).
## Development Commands

View File

@@ -77,7 +77,7 @@ Please review the following critical information before submitting your Pull Req
Our core team is currently focused on significant architectural updates that involve these data structures. To ensure stability and focus during this period, contributions of this nature will be temporarily managed internally.
* **PRs that require changes to Redux state shape or IndexedDB schemas will be closed.**
* **This restriction is temporary and will be lifted with the release of `v2.0.0`.** You can track the progress of `v2.0.0` and its related discussions on issue [#10162](https://github.com/YOUR_ORG/YOUR_REPO/issues/10162) (please replace with your actual repo link).
* **This restriction is temporary and will be lifted with the release of `v2.0.0`.** You can track the progress of `v2.0.0` and its related discussions on issue [#10162](https://github.com/CherryHQ/cherry-studio/pull/10162).
We highly encourage contributions for:
* Bug fixes 🐞

View File

@@ -82,7 +82,7 @@ Cherry Studio is a desktop client that supports multiple LLM providers, availabl
1. **Diverse LLM Provider Support**:
- ☁️ Major LLM Cloud Services: OpenAI, Gemini, Anthropic, and more
- 🔗 AI Web Service Integration: Claude, Perplexity, Poe, and others
- 🔗 AI Web Service Integration: Claude, Perplexity, [Poe](https://poe.com/), and others
- 💻 Local Model Support with Ollama, LM Studio
2. **AI Assistants & Conversations**:
@@ -238,10 +238,6 @@ The Enterprise Edition addresses core challenges in team collaboration by centra
## ✨ Online Demo
> 🚧 **Public Beta Notice**
>
> The Enterprise Edition is currently in its early public beta stage, and we are actively iterating and optimizing its features. We are aware that it may not be perfectly stable yet. If you encounter any issues or have valuable suggestions during your trial, we would be very grateful if you could contact us via email to provide feedback.
**🔗 [Cherry Studio Enterprise](https://www.cherry-ai.com/enterprise)**
## Version Comparison
@@ -249,7 +245,7 @@ The Enterprise Edition addresses core challenges in team collaboration by centra
| Feature | Community Edition | Enterprise Edition |
| :---------------- | :----------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
| **Open Source** | ✅ Yes | ⭕️ Partially released to customers |
| **Cost** | Free for Personal Use / Commercial License | Buyout / Subscription Fee |
| **Cost** | [AGPL-3.0 License](https://github.com/CherryHQ/cherry-studio?tab=AGPL-3.0-1-ov-file) | Buyout / Subscription Fee |
| **Admin Backend** | — | ● Centralized **Model** Access<br>● **Employee** Management<br>● Shared **Knowledge Base**<br>● **Access** Control<br>● **Data** Backup |
| **Server** | — | ✅ Dedicated Private Deployment |
@@ -262,8 +258,12 @@ We believe the Enterprise Edition will become your team's AI productivity engine
# 🔗 Related Projects
- [new-api](https://github.com/QuantumNous/new-api): The next-generation LLM gateway and AI asset management system supports multiple languages.
- [one-api](https://github.com/songquanpeng/one-api): LLM API management and distribution system supporting mainstream models like OpenAI, Azure, and Anthropic. Features a unified API interface, suitable for key management and secondary distribution.
- [Poe](https://poe.com/): Poe gives you access to the best AI, all in one place. Explore GPT-5, Claude Opus 4.1, DeepSeek-R1, Veo 3, ElevenLabs, and millions of others.
- [ublacklist](https://github.com/iorate/ublacklist): Blocks specific sites from appearing in Google search results
# 🚀 Contributors

View File

@@ -21,7 +21,11 @@
"quoteStyle": "single"
}
},
"files": { "ignoreUnknown": false },
"files": {
"ignoreUnknown": false,
"includes": ["**", "!**/.claude/**"],
"maxSize": 2097152
},
"formatter": {
"attributePosition": "auto",
"bracketSameLine": false,

View File

@@ -1,21 +0,0 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"aliases": {
"components": "@renderer/ui/third-party",
"hooks": "@renderer/hooks",
"lib": "@renderer/lib",
"ui": "@renderer/ui",
"utils": "@renderer/utils"
},
"iconLibrary": "lucide",
"rsc": false,
"style": "new-york",
"tailwind": {
"baseColor": "zinc",
"config": "",
"css": "src/renderer/src/assets/styles/tailwind.css",
"cssVariables": true,
"prefix": ""
},
"tsx": true
}

View File

@@ -81,7 +81,7 @@ git commit --signoff -m "Your commit message"
我们的核心团队目前正专注于涉及这些数据结构的关键架构更新和基础工作。为确保在此期间的稳定性与专注,此类贡献将暂时由内部进行管理。
* **需要更改 Redux 状态结构或 IndexedDB schema 的 PR 将会被关闭。**
* **此限制是临时性的,并将在 `v2.0.0` 版本发布后解除。** 您可以通过 Issue [#10162](https://github.com/YOUR_ORG/YOUR_REPO/issues/10162) (请替换为您的实际仓库链接) 跟踪 `v2.0.0` 的进展及相关讨论。
* **此限制是临时性的,并将在 `v2.0.0` 版本发布后解除。** 您可以通过 Issue [#10162](https://github.com/CherryHQ/cherry-studio/pull/10162) 跟踪 `v2.0.0` 的进展及相关讨论。
我们非常鼓励以下类型的贡献:
* 错误修复 🐞

View File

@@ -18,13 +18,13 @@ yarn
### Setup Node.js
Download and install [Node.js v20.x.x](https://nodejs.org/en/download)
Download and install [Node.js v22.x.x](https://nodejs.org/en/download)
### Setup Yarn
```bash
corepack enable
corepack prepare yarn@4.6.0 --activate
corepack prepare yarn@4.9.1 --activate
```
### Install Dependencies

View File

@@ -1,260 +0,0 @@
> [!NOTE]
> This technical documentation was automatically generated by Claude Code based on analysis of the current OCR implementation in the codebase. The content reflects the architecture as of the current branch state.
# OCR Architecture
## Overview
Cherry Studio's OCR (Optical Character Recognition) system is a modular, extensible architecture designed to support multiple OCR providers and file types. The architecture follows a layered approach with clear separation of concerns between data access, business logic, and provider implementations.
## Architecture Layers
The OCR architecture follows a layered approach where data interactions occur through RESTful APIs, while IPC serves as part of the API layer, allowing the renderer to interact directly with the business layer:
### 1. API Layer
**Location**: `src/main/data/api/handlers/`, `src/main/ipc.ts`, `src/preload/index.ts`
- **IPC Bridge**: Serves as API layer connecting renderer to main process
- **Request Routing**: Routes IPC calls to appropriate service methods
- **Type Safety**: Zod schemas for request/response validation
- **Error Handling**: Centralized error propagation across process boundaries
- **Security**: Secure communication sandbox between renderer and main processes
### 2. OCR Service Layer (Business Layer)
**Location**: `src/main/services/ocr/`
- **OcrService**: Main business logic orchestrator and central coordinator
- **Provider Registry**: Manages registered OCR providers
- **Data Integration**: Direct interaction with data layer for provider management
- **Lifecycle Management**: Handles provider initialization and disposal
- **Validation**: Ensures provider availability and data integrity
- **Orchestration**: Coordinates between providers and data services
- **Direct IPC Access**: Renderer can directly invoke business layer methods via IPC
### 3. Provider Services Layer
**Location**: `src/main/services/ocr/builtin/`
- **Base Service**: Abstract `OcrBaseService` defines common interface
- **Data Independence**: No direct database interactions, relies on injected data
- **Built-in Providers**:
- `TesseractService`: Local Tesseract.js implementation
- `SystemOcrService`: Platform-specific system OCR
- `PpocrService`: PaddleOCR integration
- `OvOcrService`: Intel OpenVINO (NPU) OCR
- **Pure OCR Logic**: Focus solely on OCR processing capabilities
### 4. Data Layer
**Location**: `src/main/data/db/schemas/ocr/`, `src/main/data/repositories/`
- **Database Schema**: Uses Drizzle ORM with SQLite database
- **Repository Pattern**: `OcrProviderRepository` handles all database operations
- **Provider Storage**: Stores provider configurations in `ocr_provider` table
- **JSON Configuration**: Polymorphic `config` field stores provider-specific settings
- **Data Access**: Exclusively accessed by OCR Service layer
### 5. Frontend Layer
**Location**: `src/renderer/src/services/ocr/`, `src/renderer/src/hooks/ocr/`
- **Direct IPC Communication**: Direct interaction with business layer via IPC
- **React Hooks**: Custom hooks for OCR operations and state management
- **Configuration UI**: Settings pages for provider configuration
- **State Management**: Frontend state synchronization with backend data
## Data Flow
```mermaid
graph TD
A[Frontend UI] --> B[Frontend OCR Service]
B --> C[API Layer - IPC Bridge]
C --> D[OCR Service Layer - Business Logic]
D --> E[Data Layer - Provider Repository]
D --> F[Provider Services Layer]
F --> G[OCR Processing]
G --> H[Result]
H --> F
F --> D
D --> C
C --> B
B --> A
style D fill:#e1f5fe
style F fill:#f3e5f5
style E fill:#e8f5e8
style C fill:#fff3e0
```
**Key Flow Characteristics:**
- **Direct Business Access**: Frontend communicates directly with OCR Service layer via IPC
- **IPC as API Gateway**: IPC bridge functions as the API layer, handling routing and validation
- **Data Isolation**: Only business layer interacts with data persistence
- **Provider Independence**: OCR providers remain isolated from data concerns
## Provider System
### Provider Registration
- **Built-in Providers**: Automatically registered on service initialization
- **Custom Providers**: Support for extensible provider system
- **Configuration**: Each provider has its own configuration schema
### Provider Capabilities
```typescript
interface OcrProviderCapabilityRecord {
image?: boolean // Image file OCR support
pdf?: boolean // PDF file OCR support (future)
}
```
### Configuration Architecture
- **Polymorphic Config**: JSON-based configuration adapts to provider needs
- **Type Safety**: Zod schemas validate provider-specific configurations
- **Runtime Validation**: Configuration validation before OCR operations
## Type System
### Core Types
- **`OcrProvider`**: Base provider interface
- **`OcrParams`**: OCR operation parameters
- **`OcrResult`**: Standardized OCR result format
- **`SupportedOcrFile`**: File types supported for OCR
### Business Types
- **`OcrProviderBusiness`**: Domain-level provider representation
- **Operations**: Create, Update, Replace, Delete operations
- **Queries**: List providers with filtering options
### Provider-Specific Types
- **TesseractConfig**: Language selection, model paths
- **SystemOcrConfig**: Language preferences
- **PaddleOCRConfig**: API endpoints, authentication
- **OpenVINOConfig**: Device selection, model paths
## Built-in Providers
### Tesseract OCR
- **Engine**: Tesseract.js
- **Languages**: Multi-language support with automatic download
- **Configuration**: Language selection, cache management
- **Performance**: Worker pooling for concurrent processing
### System OCR
- **Windows**: Windows Media Foundation OCR
- **macOS**: Vision framework OCR
- **Linux**: Platform-specific implementations
- **Features**: Native performance, system integration
### PaddleOCR
- **Deployment**: Remote API integration
- **Languages**: Chinese, English, and mixed language support
- **Configuration**: API endpoints and authentication
### Intel OpenVINO OCR
- **Hardware**: NPU acceleration support
- **Performance**: Optimized for Intel hardware
- **Use Case**: High-performance OCR scenarios
## Configuration Management
### Database Schema
```sql
CREATE TABLE ocr_provider (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
capabilities TEXT NOT NULL, -- JSON
config TEXT NOT NULL, -- JSON
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
```
### Provider Defaults
- **Initial Configuration**: Defined in `packages/shared/config/ocr.ts`
- **Migration System**: Automatic provider initialization on startup
- **User Customization**: Runtime configuration updates
## Error Handling
### Error Categories
- **Provider Errors**: OCR engine failures, missing dependencies
- **Configuration Errors**: Invalid settings, missing parameters
- **File Errors**: Unsupported formats, corrupted files
- **System Errors**: Resource exhaustion, permissions
### Error Propagation
- **Logging**: Centralized logging with context
- **User Feedback**: Translated error messages
- **Recovery**: Graceful fallback options
## Performance Considerations
### Resource Management
- **Worker Disposal**: Proper cleanup of OCR workers
- **Memory Management**: Limits on file sizes and concurrent operations
- **Caching**: Model and result caching where applicable
### Optimization
- **Lazy Loading**: Providers initialized on demand
- **Concurrent Processing**: Multiple workers for parallel operations
- **Hardware Acceleration**: NPU and GPU support where available
## Security
### Input Validation
- **File Type Checking**: Strict validation of supported formats
- **Size Limits**: Protection against resource exhaustion
- **Path Validation**: Prevention of path traversal attacks
### Configuration Security
- **API Key Storage**: Secure storage of sensitive configuration
- **Validation**: Runtime validation of configuration parameters
- **Sandboxing**: Isolated execution of OCR operations
## Extension Points
### Custom Providers
- **Interface**: Implement `OcrBaseService` for new providers
- **Registration**: Dynamic provider registration system
- **Configuration**: Extensible configuration schemas
### File Type Support
- **Handlers**: Modular file type processors
- **Capabilities**: Declarative provider capabilities
- **Future Support**: PDF, document formats planned
## Migration Strategy
### Legacy System
- **Data Migration**: Automatic migration from old configuration formats
- **Compatibility**: Backward compatibility during transition
- **Testing**: Comprehensive test coverage for migration paths
### Future Enhancements
- **PDF Support**: Planned extension to document OCR
- **Cloud Providers**: API-based OCR services integration
- **AI Enhancement**: Post-processing and accuracy improvements
## Development Guidelines
### Adding New Providers
1. Create provider service extending `OcrBaseService`
2. Define provider-specific configuration schema
3. Register provider in `OcrService`
4. Add configuration UI components
5. Include comprehensive tests
> [!WARNING]
> Provider services should never directly access the data layer. All data operations must go through the OCR Service layer to maintain proper separation of concerns.
### Configuration Changes
1. Update provider configuration schema
2. Add migration logic for existing configurations
3. Update UI validation and error handling
4. Test with various configuration scenarios
> [!WARNING]
> Always validate configuration changes before saving to the database. Use Zod schemas for runtime validation to prevent corrupted provider configurations.
### Testing
- **Unit Tests**: Provider implementation testing
- **Integration Tests**: End-to-end OCR workflows
- **Performance Tests**: Resource usage and timing
- **Error Scenarios**: Comprehensive error handling testing

View File

@@ -1,260 +0,0 @@
> [!NOTE]
> 本技术文档由 Claude Code 基于对当前代码库中 OCR 实现的分析自动生成。内容反映了当前分支状态的架构设计。
# OCR 架构文档
## 概述
Cherry Studio 的 OCR光学字符识别系统是一个模块化、可扩展的架构旨在支持多个 OCR 提供商和文件类型。该架构采用分层设计,在数据访问、业务逻辑和提供商实现之间有明确的关注点分离。
## 架构分层
OCR 架构采用分层方法,其中数据交互通过 RESTful API 进行,而 IPC 作为 API 层的一部分,允许 Renderer 直接与业务层交互:
### 1. API 层
**位置**: `src/main/data/api/handlers/`, `src/main/ipc.ts`, `src/preload/index.ts`
- **IPC 桥接**: 作为 API 层连接 Renderer 到主进程
- **请求路由**: 将 IPC 调用路由到相应的服务方法
- **类型安全**: 使用 Zod 模式进行请求/响应验证
- **错误处理**: 跨进程边界的集中式错误传播
- **安全**: Renderer 和主进程之间的安全通信沙盒
### 2. OCR 服务层(业务层)
**位置**: `src/main/services/ocr/`
- **OcrService**: 主要业务逻辑协调器和中央协调器
- **提供商注册表**: 管理已注册的 OCR 提供商
- **数据集成**: 与数据层直接交互进行提供商管理
- **生命周期管理**: 处理提供商初始化和销毁
- **验证**: 确保提供商可用性和数据完整性
- **协调**: 协调提供商和数据服务之间的交互
- **直接 IPC 访问**: Renderer 可通过 IPC 直接调用业务层方法
### 3. 提供商服务层
**位置**: `src/main/services/ocr/builtin/`
- **基础服务**: 抽象的 `OcrBaseService` 定义通用接口
- **数据独立性**: 无直接数据库交互,依赖外部传入的数据
- **内置提供商**:
- `TesseractService`: 本地 Tesseract.js 实现
- `SystemOcrService`: 平台特定的系统 OCR
- `PpocrService`: PaddleOCR 集成
- `OvOcrService`: Intel OpenVINO (NPU) OCR
- **纯 OCR 逻辑**: 专注于 OCR 处理能力
### 4. 数据层
**位置**: `src/main/data/db/schemas/ocr/`, `src/main/data/repositories/`
- **数据库架构**: 使用 Drizzle ORM 和 SQLite 数据库
- **仓储模式**: `OcrProviderRepository` 处理所有数据库操作
- **提供商存储**: 在 `ocr_provider` 表中存储提供商配置
- **JSON 配置**: 多态的 `config` 字段存储提供商特定的设置
- **数据访问**: 仅由 OCR 服务层访问
### 5. Renderer 层
**位置**: `src/renderer/src/services/ocr/`, `src/renderer/src/hooks/ocr/`
- **直接 IPC 通信**: 通过 IPC 与业务层直接交互
- **React Hooks**: 用于 OCR 操作和状态管理的自定义钩子
- **配置 UI**: 提供商配置的设置页面
- **状态管理**: Renderer 状态与后端数据同步
## 数据流
```mermaid
graph TD
A[Renderer UI] --> B[Renderer OCR 服务]
B --> C[API 层 - IPC 桥接]
C --> D[OCR 服务层 - 业务逻辑]
D --> E[数据层 - 提供商仓储]
D --> F[提供商服务层]
F --> G[OCR 处理]
G --> H[结果]
H --> F
F --> D
D --> C
C --> B
B --> A
style D fill:#e1f5fe
style F fill:#f3e5f5
style E fill:#e8f5e8
style C fill:#fff3e0
```
**关键流程特征**:
- **直接业务访问**: Renderer 通过 IPC 与 OCR 服务层直接通信
- **IPC 作为 API 网关**: IPC 桥接作为 API 层,处理路由和验证
- **数据隔离**: 只有业务层与数据持久化交互
- **提供商独立性**: OCR 提供商保持与数据关注点的隔离
## 提供商系统
### 提供商注册
- **内置提供商**: 在服务初始化时自动注册
- **自定义提供商**: 支持可扩展的提供商系统
- **配置**: 每个提供商都有自己的配置模式
### 提供商能力
```typescript
interface OcrProviderCapabilityRecord {
image?: boolean // 图像文件 OCR 支持
pdf?: boolean // PDF 文件 OCR 支持(未来)
}
```
### 配置架构
- **多态配置**: 基于 JSON 的配置适应提供商需求
- **类型安全**: Zod 模式验证提供商特定的配置
- **运行时验证**: OCR 操作前的配置验证
## 类型系统
### 核心类型
- **`OcrProvider`**: 基础提供商接口
- **`OcrParams`**: OCR 操作参数
- **`OcrResult`**: 标准化的 OCR 结果格式
- **`SupportedOcrFile`**: 支持 OCR 的文件类型
### 业务类型
- **`OcrProviderBusiness`**: 域级别的提供商表示
- **操作**: 创建、更新、替换、删除操作
- **查询**: 带过滤选项的提供商列表
### 提供商特定类型
- **TesseractConfig**: 语言选择、模型路径
- **SystemOcrConfig**: 语言偏好
- **PaddleOCRConfig**: API 端点、认证
- **OpenVINOConfig**: 设备选择、模型路径
## 内置提供商
### Tesseract OCR
- **引擎**: Tesseract.js
- **语言**: 支持多语言,自动下载
- **配置**: 语言选择、缓存管理
- **性能**: 工作池用于并发处理
### 系统 OCR
- **Windows**: Windows Media Foundation OCR
- **macOS**: Vision 框架 OCR
- **Linux**: 平台特定实现
- **特性**: 原生性能、系统集成
### PaddleOCR
- **部署**: 远程 API 集成
- **语言**: 中文、英文和混合语言支持
- **配置**: API 端点和认证
### Intel OpenVINO OCR
- **硬件**: NPU 加速支持
- **性能**: 为 Intel 硬件优化
- **用例**: 高性能 OCR 场景
## 配置管理
### 数据库架构
```sql
CREATE TABLE ocr_provider (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
capabilities TEXT NOT NULL, -- JSON
config TEXT NOT NULL, -- JSON
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
```
### 提供商默认值
- **初始配置**: 在 `packages/shared/config/ocr.ts` 中定义
- **迁移系统**: 启动时自动提供商初始化
- **用户自定义**: 运行时配置更新
## 错误处理
### 错误类别
- **提供商错误**: OCR 引擎故障、缺少依赖
- **配置错误**: 无效设置、缺少参数
- **文件错误**: 不支持的格式、损坏的文件
- **系统错误**: 资源耗尽、权限问题
### 错误传播
- **日志**: 带上下文的集中日志记录
- **用户反馈**: 翻译的错误消息
- **恢复**: 优雅的回退选项
## 性能考虑
### 资源管理
- **工作器销毁**: OCR 工作器的适当清理
- **内存管理**: 文件大小和并发操作限制
- **缓存**: 模型和结果缓存(如适用)
### 优化
- **延迟加载**: 按需初始化提供商
- **并发处理**: 多工作器用于并行操作
- **硬件加速**: NPU 和 GPU 支持(如可用)
## 安全
### 输入验证
- **文件类型检查**: 严格验证支持的格式
- **大小限制**: 防止资源耗尽
- **路径验证**: 防止路径遍历攻击
### 配置安全
- **API 密钥存储**: 敏感配置的安全存储
- **验证**: 配置参数的运行时验证
- **沙盒**: OCR 操作的隔离执行
## 扩展点
### 自定义提供商
- **接口**: 为新提供商实现 `OcrBaseService`
- **注册**: 动态提供商注册系统
- **配置**: 可扩展的配置模式
### 文件类型支持
- **处理器**: 模块化文件类型处理器
- **能力**: 声明式提供商能力
- **未来支持**: PDF、文档格式计划中
## 迁移策略
### 遗留系统
- **数据迁移**: 从旧配置格式自动迁移
- **兼容性**: 过渡期间的向后兼容性
- **测试**: 迁移路径的全面测试覆盖
### 未来增强
- **PDF 支持**: 计划扩展到文档 OCR
- **云提供商**: 基于 API 的 OCR 服务集成
- **AI 增强**: 后处理和准确性改进
## 开发指南
### 添加新提供商
1. 创建扩展 `OcrBaseService` 的提供商服务
2. 定义提供商特定的配置模式
3.`OcrService` 中注册提供商
4. 添加配置 UI 组件
5. 包含全面的测试
> [!WARNING]
> 提供商服务绝不应直接访问数据层。所有数据操作必须通过 OCR 服务层进行,以保持适当的关注点分离。
### 配置更改
1. 更新提供商配置模式
2. 为现有配置添加迁移逻辑
3. 更新 UI 验证和错误处理
4. 测试各种配置场景
> [!WARNING]
> 在保存到数据库之前,务必验证配置更改。使用 Zod 模式进行运行时验证,防止提供商配置损坏。
### 测试
- **单元测试**: 提供商实现测试
- **集成测试**: 端到端 OCR 工作流
- **性能测试**: 资源使用和时间
- **错误场景**: 全面的错误处理测试

View File

@@ -11,6 +11,8 @@ The Test Plan is divided into the RC channel and the Beta channel, with the foll
Users can enable the "Test Plan" and select the version channel in the software's `Settings` > `About`. Please note that the versions in the "Test Plan" cannot guarantee data consistency, so be sure to back up your data before using them.
After enabling the RC channel or Beta channel, if a stable version is released, users will still be upgraded to the stable version.
Users are welcome to submit issues or provide feedback through other channels for any bugs encountered during testing. Your feedback is very important to us.
## Developer Guide

View File

@@ -11,6 +11,8 @@
用户可以在软件的`设置`-`关于`中,开启“测试计划”并选择版本通道。请注意“测试计划”的版本无法保证数据的一致性,请使用前一定要备份数据。
用户选择RC版通道或Beta版通道后若发布了正式版仍旧会升级到正式版。
用户在测试过程中发现的BUG欢迎提交issue或通过其他渠道反馈。用户的反馈对我们非常重要。
## 开发者指南

View File

@@ -21,6 +21,8 @@ files:
- "**/*"
- "!**/{.vscode,.yarn,.yarn-lock,.github,.cursorrules,.prettierrc}"
- "!electron.vite.config.{js,ts,mjs,cjs}}"
- "!.*"
- "!components.json"
- "!**/{.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}"
@@ -67,6 +69,10 @@ asarUnpack:
extraResources:
- from: "migrations/sqlite-drizzle"
to: "migrations/sqlite-drizzle"
# copy from node_modules/claude-code-plugins/plugins to resources/data/claude-code-pluginso
- from: "./node_modules/claude-code-plugins/plugins/"
to: "claude-code-plugins"
win:
executableName: Cherry Studio
artifactName: ${productName}-${version}-${arch}-setup.${ext}
@@ -130,60 +136,50 @@ artifactBuildCompleted: scripts/artifact-build-completed.js
releaseInfo:
releaseNotes: |
<!--LANG:en-->
What's New in v1.7.0-beta.2
What's New in v1.7.0-beta.5
New Features:
- Session Settings: Manage session-specific settings and model configurations independently
- Notes Full-Text Search: Search across all notes with match highlighting
- Built-in DiDi MCP Server: Integration with DiDi ride-hailing services (China only)
- Intel OV OCR: Hardware-accelerated OCR using Intel NPU
- Auto-start API Server: Automatically starts when agents exist
- MCPRouter Provider: Added MCPRouter provider integration with token management and server synchronization
- MCP Marketplace: Enhanced MCP server discovery and management with multi-provider marketplace support
- Agent Permission Mode Display: Visual permission mode cards in empty session states
- Assistant Subscription Settings: Added subscription URL management in assistant presets
Improvements:
- Agent model selection now requires explicit user choice
- Added Mistral AI provider support
- Added NewAPI generic provider support
- Improved navbar layout consistency across different modes
- Enhanced chat component responsiveness
- Better code block display on small screens
- Updated OVMS to 2025.3 official release
- Added Greek language support
- UI Optimization: Sidebar tooltip placement improved on macOS to avoid overlapping window controls
- MCP Server Logos: Display server logos in Agent settings tooling section
- Long Command Handling: Bash command tags now auto-truncate (hover to view full command for commands over 100 chars)
- MCP OAuth Callback: Fixed callback page hanging and added multilingual support (10 languages)
- Error Display: Improved error block display order for better readability
- Plugin Browser: Centered tab alignment for better visual consistency
Bug Fixes:
- Fixed GitHub Copilot gpt-5-codex streaming issues
- Fixed assistant creation failures
- Fixed translate auto-copy functionality
- Fixed miniapps external link opening
- Fixed message layout and overflow issues
- Fixed API key parsing to preserve spaces
- Fixed agent display in different navbar layouts
- Fixed Agent sessions not inheriting allowed_tools configuration
- Fixed Gemini endpoint thinking budget spelling error
- Fixed MCP card description text overflow
- Fixed unnecessary message timestamp updates on UI-only state changes
- Updated dependencies: Bun to 1.3.1, uv to 0.9.5
<!--LANG:zh-CN-->
v1.7.0-beta.2 新特性
v1.7.0-beta.5 新特性
新功能:
- 会话设置:独立管理会话特定的设置和模型配置
- 笔记全文搜索:跨所有笔记搜索并高亮匹配内容
- 内置滴滴 MCP 服务器:集成滴滴打车服务(仅限中国地区)
- Intel OV OCR使用 Intel NPU 的硬件加速 OCR
- 自动启动 API 服务器:当存在 Agent 时自动启动
- MCPRouter 提供商:新增 MCPRouter 提供商集成,支持 token 管理和服务器同步
- MCP 市场:增强 MCP 服务器发现和管理功能,支持多提供商市场
- Agent 权限模式展示:空会话状态显示可视化权限模式卡片
- 助手订阅设置:在助手预设中添加订阅 URL 管理功能
改进:
- Agent 模型选择现在需要用户显式选择
- 添加 Mistral AI 提供商支持
- 添加 NewAPI 通用提供商支持
- 改进不同模式下的导航栏布局一致性
- 增强聊天组件响应式设计
- 优化小屏幕代码块显示
- 更新 OVMS 至 2025.3 正式版
- 添加希腊语支持
- UI 优化macOS 上侧边栏工具提示位置优化,避免与窗口控制按钮重叠
- MCP 服务器标志:在 Agent 设置工具部分显示服务器 logo
- 长命令处理Bash 命令标签自动截断(超过 100 字符时悬停查看完整内容)
- MCP OAuth 回调修复回调页面挂起问题并添加多语言支持10 种语言)
- 错误信息展示:改进错误块显示顺序,提高可读性
- 插件浏览器:标签页居中对齐,视觉效果更统一
问题修复:
- 修复 GitHub Copilot gpt-5-codex 流式传输问题
- 修复助手创建失败
- 修复翻译自动复制功能
- 修复小程序外部链接打开
- 修复消息布局和溢出问题
- 修复 API 密钥解析以保留空格
- 修复不同导航栏布局中的 Agent 显示
- 修复 Agent 会话未继承 allowed_tools 配置
- 修复 Gemini 端点 thinking budget 拼写错误
- 修复 MCP 卡片描述文本溢出问题
- 修复仅 UI 状态变化时消息时间戳不必要的更新
- 依赖更新Bun 升级到 1.3.1uv 升级到 0.9.5
<!--LANG:END-->

View File

@@ -111,6 +111,7 @@ export default defineConfig({
'@cherrystudio/ai-core/built-in/plugins': resolve('packages/aiCore/src/core/plugins/built-in'),
'@cherrystudio/ai-core': resolve('packages/aiCore/src'),
'@cherrystudio/extension-table-plus': resolve('packages/extension-table-plus/src'),
'@cherrystudio/ai-sdk-provider': resolve('packages/ai-sdk-provider/src'),
'@cherrystudio/ui': resolve('packages/ui/src')
}
},

View File

@@ -142,24 +142,19 @@ export default defineConfig([
files: ['**/*.{ts,tsx,js,jsx}'],
ignores: ['src/renderer/src/windows/dataRefactorTest/**/*.{ts,tsx}'],
rules: {
'no-restricted-imports': [
'error',
{
paths: [
{
name: 'antd',
importNames: ['Flex', 'Switch', 'message', 'Button', 'Tooltip'],
message:
'❌ Do not import this component from antd. Use our custom components instead: import { ... } from "@cherrystudio/ui"'
},
// {
// name: '@heroui/react',
// message:
// '❌ Do not import components from heroui directly. Use our wrapped components instead: import { ... } from "@cherrystudio/ui"'
// }
]
}
]
// 'no-restricted-imports': [
// 'error',
// {
// paths: [
// {
// name: 'antd',
// importNames: ['Flex', 'Switch', 'message', 'Button', 'Tooltip'],
// message:
// '❌ Do not import this component from antd. Use our custom components instead: import { ... } from "@cherrystudio/ui"'
// }
// ]
// }
// ]
}
},
])

View File

@@ -1,10 +0,0 @@
CREATE TABLE `ocr_provider` (
`id` text PRIMARY KEY NOT NULL,
`name` text NOT NULL,
`capabilities` text NOT NULL,
`config` text NOT NULL,
`created_at` integer,
`updated_at` integer
);
--> statement-breakpoint
CREATE INDEX `name` ON `ocr_provider` (`name`);

View File

@@ -1,172 +0,0 @@
{
"version": "6",
"dialect": "sqlite",
"id": "64f7ad88-7111-4574-988c-d7ef429e375d",
"prevId": "de8009d7-95b9-4f99-99fa-4b8795708f21",
"tables": {
"app_state": {
"name": "app_state",
"columns": {
"key": {
"name": "key",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"ocr_provider": {
"name": "ocr_provider",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"capabilities": {
"name": "capabilities",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"config": {
"name": "config",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"name": {
"name": "name",
"columns": ["name"],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"preference": {
"name": "preference",
"columns": {
"scope": {
"name": "scope",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"key": {
"name": "key",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"updated_at": {
"name": "updated_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"scope_name_idx": {
"name": "scope_name_idx",
"columns": ["scope", "key"],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

View File

@@ -7,13 +7,6 @@
"tag": "0000_solid_lord_hawal",
"version": "6",
"when": 1754745234572
},
{
"idx": 1,
"version": "6",
"when": 1760969721294,
"tag": "0001_previous_sir_ram",
"breakpoints": true
}
],
"version": "7"

View File

@@ -81,21 +81,25 @@
"release:aicore": "yarn workspace @cherrystudio/ai-core version patch --immediate && yarn workspace @cherrystudio/ai-core npm publish --access public"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "patch:@anthropic-ai/claude-agent-sdk@npm%3A0.1.1#~/.yarn/patches/@anthropic-ai-claude-agent-sdk-npm-0.1.1-d937b73fed.patch",
"@anthropic-ai/claude-agent-sdk": "patch:@anthropic-ai/claude-agent-sdk@npm%3A0.1.30#~/.yarn/patches/@anthropic-ai-claude-agent-sdk-npm-0.1.30-b50a299674.patch",
"@libsql/client": "0.14.0",
"@libsql/win32-x64-msvc": "^0.4.7",
"@napi-rs/system-ocr": "patch:@napi-rs/system-ocr@npm%3A1.0.2#~/.yarn/patches/@napi-rs-system-ocr-npm-1.0.2-59e7a78e8b.patch",
"@radix-ui/react-tabs": "^1.1.13",
"@paymoapp/electron-shutdown-handler": "^1.1.2",
"@strongtz/win32-arm64-msvc": "^0.4.7",
"express": "^5.1.0",
"font-list": "^2.0.0",
"graceful-fs": "^4.2.11",
"gray-matter": "^4.0.3",
"js-yaml": "^4.1.0",
"jsdom": "26.1.0",
"node-stream-zip": "^1.15.0",
"officeparser": "^4.2.0",
"os-proxy-config": "^1.1.2",
"qrcode.react": "^4.2.0",
"selection-hook": "^1.0.12",
"sharp": "0.34.4",
"sharp": "^0.34.3",
"socket.io": "^4.8.1",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"tesseract.js": "patch:tesseract.js@npm%3A6.0.1#~/.yarn/patches/tesseract.js-npm-6.0.1-2562a7e46d.patch",
@@ -105,17 +109,17 @@
"@agentic/exa": "^7.3.3",
"@agentic/searxng": "^7.3.3",
"@agentic/tavily": "^7.3.3",
"@ai-sdk/amazon-bedrock": "^3.0.35",
"@ai-sdk/google-vertex": "^3.0.40",
"@ai-sdk/huggingface": "patch:@ai-sdk/huggingface@npm%3A0.0.4#~/.yarn/patches/@ai-sdk-huggingface-npm-0.0.4-8080836bc1.patch",
"@ai-sdk/mistral": "^2.0.19",
"@ai-sdk/perplexity": "^2.0.13",
"@ai-sdk/amazon-bedrock": "^3.0.53",
"@ai-sdk/google-vertex": "^3.0.62",
"@ai-sdk/huggingface": "patch:@ai-sdk/huggingface@npm%3A0.0.8#~/.yarn/patches/@ai-sdk-huggingface-npm-0.0.8-d4d0aaac93.patch",
"@ai-sdk/mistral": "^2.0.23",
"@ai-sdk/perplexity": "^2.0.17",
"@ant-design/v5-patch-for-react-19": "^1.0.3",
"@anthropic-ai/sdk": "^0.41.0",
"@anthropic-ai/vertex-sdk": "patch:@anthropic-ai/vertex-sdk@npm%3A0.11.4#~/.yarn/patches/@anthropic-ai-vertex-sdk-npm-0.11.4-c19cb41edb.patch",
"@aws-sdk/client-bedrock": "^3.840.0",
"@aws-sdk/client-bedrock-runtime": "^3.840.0",
"@aws-sdk/client-s3": "^3.840.0",
"@aws-sdk/client-bedrock": "^3.910.0",
"@aws-sdk/client-bedrock-runtime": "^3.910.0",
"@aws-sdk/client-s3": "^3.910.0",
"@biomejs/biome": "2.2.4",
"@cherrystudio/ai-core": "workspace:^1.0.0-alpha.18",
"@cherrystudio/embedjs": "^0.1.31",
@@ -147,8 +151,9 @@
"@eslint/js": "^9.22.0",
"@google/genai": "patch:@google/genai@npm%3A1.0.1#~/.yarn/patches/@google-genai-npm-1.0.1-e26f0f9af7.patch",
"@hello-pangea/dnd": "^18.0.1",
"@heroui/react": "^2.8.3",
"@langchain/community": "^0.3.50",
"@langchain/community": "^1.0.0",
"@langchain/core": "patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch",
"@langchain/openai": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
"@mistralai/mistralai": "^1.7.5",
"@modelcontextprotocol/sdk": "^1.17.5",
"@mozilla/readability": "^0.6.0",
@@ -199,6 +204,7 @@
"@types/fs-extra": "^11",
"@types/he": "^1",
"@types/html-to-text": "^9",
"@types/js-yaml": "^4.0.9",
"@types/lodash": "^4.17.5",
"@types/markdown-it": "^14",
"@types/md5": "^2.3.5",
@@ -228,7 +234,7 @@
"@viz-js/lang-dot": "^1.0.5",
"@viz-js/viz": "^3.14.0",
"@xyflow/react": "^12.4.4",
"ai": "^5.0.68",
"ai": "^5.0.90",
"antd": "patch:antd@npm%3A5.27.0#~/.yarn/patches/antd-npm-5.27.0-aa91c36546.patch",
"archiver": "^7.0.1",
"async-mutex": "^0.5.0",
@@ -238,6 +244,7 @@
"check-disk-space": "3.4.0",
"cheerio": "^1.1.2",
"chokidar": "^4.0.3",
"claude-code-plugins": "1.0.3",
"cli-progress": "^3.12.0",
"clsx": "^2.1.1",
"code-inspector-plugin": "^0.20.14",
@@ -344,6 +351,7 @@
"striptags": "^3.2.0",
"styled-components": "^6.1.11",
"swr": "^2.3.6",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.13",
"tar": "^7.4.3",
"tiny-pinyin": "^1.3.2",
@@ -369,12 +377,11 @@
"zod": "^4.1.5"
},
"resolutions": {
"@smithy/types": "4.7.1",
"@codemirror/language": "6.11.3",
"@codemirror/lint": "6.8.5",
"@codemirror/view": "6.38.1",
"@langchain/core@npm:^0.3.26": "patch:@langchain/core@npm%3A0.3.44#~/.yarn/patches/@langchain-core-npm-0.3.44-41d5c3cb0a.patch",
"@langchain/openai@npm:^0.3.16": "patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch",
"@langchain/openai@npm:>=0.1.0 <0.4.0": "patch:@langchain/openai@npm%3A0.3.16#~/.yarn/patches/@langchain-openai-npm-0.3.16-e525b59526.patch",
"@langchain/core@npm:^0.3.26": "patch:@langchain/core@npm%3A1.0.2#~/.yarn/patches/@langchain-core-npm-1.0.2-183ef83fe4.patch",
"app-builder-lib@npm:26.0.13": "patch:app-builder-lib@npm%3A26.0.13#~/.yarn/patches/app-builder-lib-npm-26.0.13-a064c9e1d0.patch",
"app-builder-lib@npm:26.0.15": "patch:app-builder-lib@npm%3A26.0.15#~/.yarn/patches/app-builder-lib-npm-26.0.15-360e5b0476.patch",
"atomically@npm:^1.7.0": "patch:atomically@npm%3A1.7.0#~/.yarn/patches/atomically-npm-1.7.0-e742e5293b.patch",
@@ -390,14 +397,20 @@
"undici": "6.21.2",
"vite": "npm:rolldown-vite@7.1.5",
"tesseract.js@npm:*": "patch:tesseract.js@npm%3A6.0.1#~/.yarn/patches/tesseract.js-npm-6.0.1-2562a7e46d.patch",
"@ai-sdk/google@npm:2.0.20": "patch:@ai-sdk/google@npm%3A2.0.20#~/.yarn/patches/@ai-sdk-google-npm-2.0.20-b9102f9d54.patch",
"@img/sharp-darwin-arm64": "0.34.4",
"@img/sharp-darwin-x64": "0.34.4",
"@img/sharp-linux-arm": "0.34.4",
"@img/sharp-linux-arm64": "0.34.4",
"@img/sharp-linux-x64": "0.34.4",
"@img/sharp-win32-x64": "0.34.4",
"openai@npm:5.12.2": "npm:@cherrystudio/openai@6.5.0"
"@ai-sdk/openai@npm:^2.0.52": "patch:@ai-sdk/openai@npm%3A2.0.52#~/.yarn/patches/@ai-sdk-openai-npm-2.0.52-b36d949c76.patch",
"@img/sharp-darwin-arm64": "0.34.3",
"@img/sharp-darwin-x64": "0.34.3",
"@img/sharp-linux-arm": "0.34.3",
"@img/sharp-linux-arm64": "0.34.3",
"@img/sharp-linux-x64": "0.34.3",
"@img/sharp-win32-x64": "0.34.3",
"openai@npm:5.12.2": "npm:@cherrystudio/openai@6.5.0",
"@langchain/openai@npm:>=0.1.0 <0.6.0": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
"@langchain/openai@npm:^0.3.16": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
"@langchain/openai@npm:>=0.2.0 <0.7.0": "patch:@langchain/openai@npm%3A1.0.0#~/.yarn/patches/@langchain-openai-npm-1.0.0-474d0ad9d4.patch",
"@ai-sdk/openai@npm:2.0.64": "patch:@ai-sdk/openai@npm%3A2.0.64#~/.yarn/patches/@ai-sdk-openai-npm-2.0.64-48f99f5bf3.patch",
"@ai-sdk/openai@npm:^2.0.42": "patch:@ai-sdk/openai@npm%3A2.0.64#~/.yarn/patches/@ai-sdk-openai-npm-2.0.64-48f99f5bf3.patch",
"@ai-sdk/google@npm:2.0.31": "patch:@ai-sdk/google@npm%3A2.0.31#~/.yarn/patches/@ai-sdk-google-npm-2.0.31-b0de047210.patch"
},
"packageManager": "yarn@4.9.1",
"lint-staged": {

View File

@@ -0,0 +1,39 @@
# @cherrystudio/ai-sdk-provider
CherryIN provider bundle for the [Vercel AI SDK](https://ai-sdk.dev/).
It exposes the CherryIN OpenAI-compatible entrypoints and dynamically routes Anthropic and Gemini model ids to their CherryIN upstream equivalents.
## Installation
```bash
npm install ai @cherrystudio/ai-sdk-provider @ai-sdk/anthropic @ai-sdk/google @ai-sdk/openai
# or
yarn add ai @cherrystudio/ai-sdk-provider @ai-sdk/anthropic @ai-sdk/google @ai-sdk/openai
```
> **Note**: This package requires peer dependencies `ai`, `@ai-sdk/anthropic`, `@ai-sdk/google`, and `@ai-sdk/openai` to be installed.
## Usage
```ts
import { createCherryIn, cherryIn } from '@cherrystudio/ai-sdk-provider'
const cherryInProvider = createCherryIn({
apiKey: process.env.CHERRYIN_API_KEY,
// optional overrides:
// baseURL: 'https://open.cherryin.net/v1',
// anthropicBaseURL: 'https://open.cherryin.net/anthropic',
// geminiBaseURL: 'https://open.cherryin.net/gemini/v1beta',
})
// Chat models will auto-route based on the model id prefix:
const openaiModel = cherryInProvider.chat('gpt-4o-mini')
const anthropicModel = cherryInProvider.chat('claude-3-5-sonnet-latest')
const geminiModel = cherryInProvider.chat('gemini-2.0-pro-exp')
const { text } = await openaiModel.invoke('Hello CherryIN!')
```
The provider also exposes `completion`, `responses`, `embedding`, `image`, `transcription`, and `speech` helpers aligned with the upstream APIs.
See [AI SDK docs](https://ai-sdk.dev/providers/community-providers/custom-providers) for configuring custom providers.

View File

@@ -0,0 +1,64 @@
{
"name": "@cherrystudio/ai-sdk-provider",
"version": "0.1.0",
"description": "Cherry Studio AI SDK provider bundle with CherryIN routing.",
"keywords": [
"ai-sdk",
"provider",
"cherryin",
"vercel-ai-sdk",
"cherry-studio"
],
"author": "Cherry Studio",
"license": "MIT",
"homepage": "https://github.com/CherryHQ/cherry-studio",
"repository": {
"type": "git",
"url": "git+https://github.com/CherryHQ/cherry-studio.git",
"directory": "packages/ai-sdk-provider"
},
"bugs": {
"url": "https://github.com/CherryHQ/cherry-studio/issues"
},
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsdown",
"dev": "tsc -w",
"clean": "rm -rf dist",
"test": "vitest run",
"test:watch": "vitest"
},
"peerDependencies": {
"@ai-sdk/anthropic": "^2.0.29",
"@ai-sdk/google": "^2.0.23",
"@ai-sdk/openai": "^2.0.64",
"ai": "^5.0.26"
},
"dependencies": {
"@ai-sdk/provider": "^2.0.0",
"@ai-sdk/provider-utils": "^3.0.12"
},
"devDependencies": {
"tsdown": "^0.13.3",
"typescript": "^5.8.2",
"vitest": "^3.2.4"
},
"sideEffects": false,
"engines": {
"node": ">=18.0.0"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
}
}
}

View File

@@ -0,0 +1,319 @@
import { AnthropicMessagesLanguageModel } from '@ai-sdk/anthropic/internal'
import { GoogleGenerativeAILanguageModel } from '@ai-sdk/google/internal'
import type { OpenAIProviderSettings } from '@ai-sdk/openai'
import {
OpenAIChatLanguageModel,
OpenAICompletionLanguageModel,
OpenAIEmbeddingModel,
OpenAIImageModel,
OpenAIResponsesLanguageModel,
OpenAISpeechModel,
OpenAITranscriptionModel
} from '@ai-sdk/openai/internal'
import {
type EmbeddingModelV2,
type ImageModelV2,
type LanguageModelV2,
type ProviderV2,
type SpeechModelV2,
type TranscriptionModelV2
} from '@ai-sdk/provider'
import type { FetchFunction } from '@ai-sdk/provider-utils'
import { loadApiKey, withoutTrailingSlash } from '@ai-sdk/provider-utils'
export const CHERRYIN_PROVIDER_NAME = 'cherryin' as const
export const DEFAULT_CHERRYIN_BASE_URL = 'https://open.cherryin.net/v1'
export const DEFAULT_CHERRYIN_ANTHROPIC_BASE_URL = 'https://open.cherryin.net/v1'
export const DEFAULT_CHERRYIN_GEMINI_BASE_URL = 'https://open.cherryin.net/v1beta/models'
const ANTHROPIC_PREFIX = /^anthropic\//i
const GEMINI_PREFIX = /^google\//i
// const GEMINI_EXCLUDED_SUFFIXES = ['-nothink', '-search']
type HeaderValue = string | undefined
type HeadersInput = Record<string, HeaderValue> | (() => Record<string, HeaderValue>)
export interface CherryInProviderSettings {
/**
* CherryIN API key.
*
* If omitted, the provider will read the `CHERRYIN_API_KEY` environment variable.
*/
apiKey?: string
/**
* Optional custom fetch implementation.
*/
fetch?: FetchFunction
/**
* Base URL for OpenAI-compatible CherryIN endpoints.
*
* Defaults to `https://open.cherryin.net/v1`.
*/
baseURL?: string
/**
* Base URL for Anthropic-compatible endpoints.
*
* Defaults to `https://open.cherryin.net/anthropic`.
*/
anthropicBaseURL?: string
/**
* Base URL for Gemini-compatible endpoints.
*
* Defaults to `https://open.cherryin.net/gemini/v1beta`.
*/
geminiBaseURL?: string
/**
* Optional static headers applied to every request.
*/
headers?: HeadersInput
}
export interface CherryInProvider extends ProviderV2 {
(modelId: string, settings?: OpenAIProviderSettings): LanguageModelV2
languageModel(modelId: string, settings?: OpenAIProviderSettings): LanguageModelV2
chat(modelId: string, settings?: OpenAIProviderSettings): LanguageModelV2
responses(modelId: string): LanguageModelV2
completion(modelId: string, settings?: OpenAIProviderSettings): LanguageModelV2
embedding(modelId: string, settings?: OpenAIProviderSettings): EmbeddingModelV2<string>
textEmbedding(modelId: string, settings?: OpenAIProviderSettings): EmbeddingModelV2<string>
textEmbeddingModel(modelId: string, settings?: OpenAIProviderSettings): EmbeddingModelV2<string>
image(modelId: string, settings?: OpenAIProviderSettings): ImageModelV2
imageModel(modelId: string, settings?: OpenAIProviderSettings): ImageModelV2
transcription(modelId: string): TranscriptionModelV2
transcriptionModel(modelId: string): TranscriptionModelV2
speech(modelId: string): SpeechModelV2
speechModel(modelId: string): SpeechModelV2
}
const resolveApiKey = (options: CherryInProviderSettings): string =>
loadApiKey({
apiKey: options.apiKey,
environmentVariableName: 'CHERRYIN_API_KEY',
description: 'CherryIN'
})
const isAnthropicModel = (modelId: string) => ANTHROPIC_PREFIX.test(modelId)
const isGeminiModel = (modelId: string) => GEMINI_PREFIX.test(modelId)
const createCustomFetch = (originalFetch?: any) => {
return async (url: string, options: any) => {
if (options?.body) {
try {
const body = JSON.parse(options.body)
if (body.tools && Array.isArray(body.tools) && body.tools.length === 0 && body.tool_choice) {
delete body.tool_choice
options.body = JSON.stringify(body)
}
} catch (error) {
// ignore error
}
}
return originalFetch ? originalFetch(url, options) : fetch(url, options)
}
}
class CherryInOpenAIChatLanguageModel extends OpenAIChatLanguageModel {
constructor(modelId: string, settings: any) {
super(modelId, {
...settings,
fetch: createCustomFetch(settings.fetch)
})
}
}
const resolveConfiguredHeaders = (headers?: HeadersInput): Record<string, HeaderValue> => {
if (typeof headers === 'function') {
return { ...headers() }
}
return headers ? { ...headers } : {}
}
const toBearerToken = (authorization?: string) => (authorization ? authorization.replace(/^Bearer\s+/i, '') : undefined)
const createJsonHeadersGetter = (options: CherryInProviderSettings): (() => Record<string, HeaderValue>) => {
return () => ({
Authorization: `Bearer ${resolveApiKey(options)}`,
'Content-Type': 'application/json',
...resolveConfiguredHeaders(options.headers)
})
}
const createAuthHeadersGetter = (options: CherryInProviderSettings): (() => Record<string, HeaderValue>) => {
return () => ({
Authorization: `Bearer ${resolveApiKey(options)}`,
...resolveConfiguredHeaders(options.headers)
})
}
export const createCherryIn = (options: CherryInProviderSettings = {}): CherryInProvider => {
const {
baseURL = DEFAULT_CHERRYIN_BASE_URL,
anthropicBaseURL = DEFAULT_CHERRYIN_ANTHROPIC_BASE_URL,
geminiBaseURL = DEFAULT_CHERRYIN_GEMINI_BASE_URL,
fetch
} = options
const getJsonHeaders = createJsonHeadersGetter(options)
const getAuthHeaders = createAuthHeadersGetter(options)
const url = ({ path }: { path: string; modelId: string }) => `${withoutTrailingSlash(baseURL)}${path}`
const createAnthropicModel = (modelId: string) =>
new AnthropicMessagesLanguageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.anthropic`,
baseURL: anthropicBaseURL,
headers: () => {
const headers = getJsonHeaders()
const apiKey = toBearerToken(headers.Authorization)
return {
...headers,
'x-api-key': apiKey
}
},
fetch,
supportedUrls: () => ({
'image/*': [/^https?:\/\/.*$/]
})
})
const createGeminiModel = (modelId: string) =>
new GoogleGenerativeAILanguageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.google`,
baseURL: geminiBaseURL,
headers: () => {
const headers = getJsonHeaders()
const apiKey = toBearerToken(headers.Authorization)
return {
...headers,
'x-goog-api-key': apiKey
}
},
fetch,
generateId: () => `${CHERRYIN_PROVIDER_NAME}-${Date.now()}`,
supportedUrls: () => ({})
})
const createOpenAIChatModel = (modelId: string, settings: OpenAIProviderSettings = {}) =>
new CherryInOpenAIChatLanguageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.openai-chat`,
url,
headers: () => ({
...getJsonHeaders(),
...settings.headers
}),
fetch
})
const createChatModel = (modelId: string, settings: OpenAIProviderSettings = {}) => {
if (isAnthropicModel(modelId)) {
return createAnthropicModel(modelId)
}
if (isGeminiModel(modelId)) {
return createGeminiModel(modelId)
}
return new OpenAIResponsesLanguageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.openai`,
url,
headers: () => ({
...getJsonHeaders(),
...settings.headers
}),
fetch
})
}
const createCompletionModel = (modelId: string, settings: OpenAIProviderSettings = {}) =>
new OpenAICompletionLanguageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.completion`,
url,
headers: () => ({
...getJsonHeaders(),
...settings.headers
}),
fetch
})
const createEmbeddingModel = (modelId: string, settings: OpenAIProviderSettings = {}) =>
new OpenAIEmbeddingModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.embeddings`,
url,
headers: () => ({
...getJsonHeaders(),
...settings.headers
}),
fetch
})
const createResponsesModel = (modelId: string) =>
new OpenAIResponsesLanguageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.responses`,
url,
headers: () => ({
...getJsonHeaders()
}),
fetch
})
const createImageModel = (modelId: string, settings: OpenAIProviderSettings = {}) =>
new OpenAIImageModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.image`,
url,
headers: () => ({
...getJsonHeaders(),
...settings.headers
}),
fetch
})
const createTranscriptionModel = (modelId: string) =>
new OpenAITranscriptionModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.transcription`,
url,
headers: () => ({
...getAuthHeaders()
}),
fetch
})
const createSpeechModel = (modelId: string) =>
new OpenAISpeechModel(modelId, {
provider: `${CHERRYIN_PROVIDER_NAME}.speech`,
url,
headers: () => ({
...getJsonHeaders()
}),
fetch
})
const provider: CherryInProvider = function (modelId: string, settings?: OpenAIProviderSettings) {
if (new.target) {
throw new Error('CherryIN provider function cannot be called with the new keyword.')
}
return createChatModel(modelId, settings)
}
provider.languageModel = createChatModel
provider.chat = createOpenAIChatModel
provider.responses = createResponsesModel
provider.completion = createCompletionModel
provider.embedding = createEmbeddingModel
provider.textEmbedding = createEmbeddingModel
provider.textEmbeddingModel = createEmbeddingModel
provider.image = createImageModel
provider.imageModel = createImageModel
provider.transcription = createTranscriptionModel
provider.transcriptionModel = createTranscriptionModel
provider.speech = createSpeechModel
provider.speechModel = createSpeechModel
return provider
}
export const cherryIn = createCherryIn()

View File

@@ -0,0 +1 @@
export * from './cherryin-provider'

View File

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

View File

@@ -0,0 +1,12 @@
import { defineConfig } from 'tsdown'
export default defineConfig({
entry: {
index: 'src/index.ts'
},
outDir: 'dist',
format: ['esm', 'cjs'],
clean: true,
dts: true,
tsconfig: 'tsconfig.json'
})

View File

@@ -36,14 +36,16 @@
"ai": "^5.0.26"
},
"dependencies": {
"@ai-sdk/anthropic": "^2.0.27",
"@ai-sdk/azure": "^2.0.49",
"@ai-sdk/deepseek": "^1.0.23",
"@ai-sdk/openai": "^2.0.48",
"@ai-sdk/openai-compatible": "^1.0.22",
"@ai-sdk/anthropic": "^2.0.43",
"@ai-sdk/azure": "^2.0.66",
"@ai-sdk/deepseek": "^1.0.27",
"@ai-sdk/google": "patch:@ai-sdk/google@npm%3A2.0.31#~/.yarn/patches/@ai-sdk-google-npm-2.0.31-b0de047210.patch",
"@ai-sdk/openai": "patch:@ai-sdk/openai@npm%3A2.0.64#~/.yarn/patches/@ai-sdk-openai-npm-2.0.64-48f99f5bf3.patch",
"@ai-sdk/openai-compatible": "^1.0.26",
"@ai-sdk/provider": "^2.0.0",
"@ai-sdk/provider-utils": "^3.0.12",
"@ai-sdk/xai": "^2.0.26",
"@ai-sdk/provider-utils": "^3.0.16",
"@ai-sdk/xai": "^2.0.31",
"@cherrystudio/ai-sdk-provider": "workspace:*",
"zod": "^4.1.5"
},
"devDependencies": {

View File

@@ -1,8 +1,9 @@
import type { anthropic } from '@ai-sdk/anthropic'
import type { google } from '@ai-sdk/google'
import type { openai } from '@ai-sdk/openai'
import { anthropic } from '@ai-sdk/anthropic'
import { google } from '@ai-sdk/google'
import { openai } from '@ai-sdk/openai'
import type { InferToolInput, InferToolOutput, Tool } from 'ai'
import { createOpenRouterOptions, createXaiOptions, mergeProviderOptions } from '../../../options'
import type { ProviderOptionsMap } from '../../../options/types'
import type { OpenRouterSearchConfig } from './openrouter'
@@ -94,3 +95,56 @@ export type WebSearchToolInputSchema = {
google: InferToolInput<GoogleWebSearchTool>
'openai-chat': InferToolInput<OpenAIChatWebSearchTool>
}
export const switchWebSearchTool = (providerId: string, config: WebSearchPluginConfig, params: any) => {
switch (providerId) {
case 'openai': {
if (config.openai) {
if (!params.tools) params.tools = {}
params.tools.web_search = openai.tools.webSearch(config.openai)
}
break
}
case 'openai-chat': {
if (config['openai-chat']) {
if (!params.tools) params.tools = {}
params.tools.web_search_preview = openai.tools.webSearchPreview(config['openai-chat'])
}
break
}
case 'anthropic': {
if (config.anthropic) {
if (!params.tools) params.tools = {}
params.tools.web_search = anthropic.tools.webSearch_20250305(config.anthropic)
}
break
}
case 'google': {
// case 'google-vertex':
if (!params.tools) params.tools = {}
params.tools.web_search = google.tools.googleSearch(config.google || {})
break
}
case 'xai': {
if (config.xai) {
const searchOptions = createXaiOptions({
searchParameters: { ...config.xai, mode: 'on' }
})
params.providerOptions = mergeProviderOptions(params.providerOptions, searchOptions)
}
break
}
case 'openrouter': {
if (config.openrouter) {
const searchOptions = createOpenRouterOptions(config.openrouter)
params.providerOptions = mergeProviderOptions(params.providerOptions, searchOptions)
}
break
}
}
return params
}

View File

@@ -2,15 +2,11 @@
* Web Search Plugin
* 提供统一的网络搜索能力,支持多个 AI Provider
*/
import { anthropic } from '@ai-sdk/anthropic'
import { google } from '@ai-sdk/google'
import { openai } from '@ai-sdk/openai'
import { createOpenRouterOptions, createXaiOptions, mergeProviderOptions } from '../../../options'
import { definePlugin } from '../../'
import type { AiRequestContext } from '../../types'
import type { WebSearchPluginConfig } from './helper'
import { DEFAULT_WEB_SEARCH_CONFIG } from './helper'
import { DEFAULT_WEB_SEARCH_CONFIG, switchWebSearchTool } from './helper'
/**
* 网络搜索插件
@@ -24,56 +20,13 @@ export const webSearchPlugin = (config: WebSearchPluginConfig = DEFAULT_WEB_SEAR
transformParams: async (params: any, context: AiRequestContext) => {
const { providerId } = context
switch (providerId) {
case 'openai': {
if (config.openai) {
if (!params.tools) params.tools = {}
params.tools.web_search = openai.tools.webSearch(config.openai)
}
break
}
case 'openai-chat': {
if (config['openai-chat']) {
if (!params.tools) params.tools = {}
params.tools.web_search_preview = openai.tools.webSearchPreview(config['openai-chat'])
}
break
}
switchWebSearchTool(providerId, config, params)
case 'anthropic': {
if (config.anthropic) {
if (!params.tools) params.tools = {}
params.tools.web_search = anthropic.tools.webSearch_20250305(config.anthropic)
}
break
}
case 'google': {
// case 'google-vertex':
if (!params.tools) params.tools = {}
params.tools.web_search = google.tools.googleSearch(config.google || {})
break
}
case 'xai': {
if (config.xai) {
const searchOptions = createXaiOptions({
searchParameters: { ...config.xai, mode: 'on' }
})
params.providerOptions = mergeProviderOptions(params.providerOptions, searchOptions)
}
break
}
case 'openrouter': {
if (config.openrouter) {
const searchOptions = createOpenRouterOptions(config.openrouter)
params.providerOptions = mergeProviderOptions(params.providerOptions, searchOptions)
}
break
}
if (providerId === 'cherryin' || providerId === 'cherryin-chat') {
// cherryin.gemini
const _providerId = params.model.provider.split('.')[1]
switchWebSearchTool(_providerId, config, params)
}
return params
}
})

View File

@@ -12,6 +12,7 @@ import { createOpenAI, type OpenAIProviderSettings } from '@ai-sdk/openai'
import { createOpenAICompatible } from '@ai-sdk/openai-compatible'
import type { LanguageModelV2 } from '@ai-sdk/provider'
import { createXai } from '@ai-sdk/xai'
import { type CherryInProviderSettings, createCherryIn } from '@cherrystudio/ai-sdk-provider'
import { createOpenRouter } from '@openrouter/ai-sdk-provider'
import type { Provider } from 'ai'
import { customProvider } from 'ai'
@@ -31,6 +32,8 @@ export const baseProviderIds = [
'azure-responses',
'deepseek',
'openrouter',
'cherryin',
'cherryin-chat',
'huggingface'
] as const
@@ -136,6 +139,26 @@ export const baseProviders = [
creator: createOpenRouter,
supportsImageGeneration: true
},
{
id: 'cherryin',
name: 'CherryIN',
creator: createCherryIn,
supportsImageGeneration: true
},
{
id: 'cherryin-chat',
name: 'CherryIN Chat',
creator: (options: CherryInProviderSettings) => {
const provider = createCherryIn(options)
return customProvider({
fallbackProvider: {
...provider,
languageModel: (modelId: string) => provider.chat(modelId)
}
})
},
supportsImageGeneration: true
},
{
id: 'huggingface',
name: 'HuggingFace',

View File

@@ -96,6 +96,10 @@ export enum IpcChannel {
AgentMessage_PersistExchange = 'agent-message:persist-exchange',
AgentMessage_GetHistory = 'agent-message:get-history',
AgentToolPermission_Request = 'agent-tool-permission:request',
AgentToolPermission_Response = 'agent-tool-permission:response',
AgentToolPermission_Result = 'agent-tool-permission:result',
//copilot
Copilot_GetAuthMessage = 'copilot:get-auth-message',
Copilot_GetCopilotToken = 'copilot:get-copilot-token',
@@ -185,6 +189,7 @@ export enum IpcChannel {
Fs_ReadText = 'fs:readText',
File_OpenWithRelativePath = 'file:openWithRelativePath',
File_IsTextFile = 'file:isTextFile',
File_ListDirectory = 'file:listDirectory',
File_GetDirectoryStructure = 'file:getDirectoryStructure',
File_CheckFileName = 'file:checkFileName',
File_ValidateNotesDirectory = 'file:validateNotesDirectory',
@@ -350,6 +355,7 @@ export enum IpcChannel {
ApiServer_Stop = 'api-server:stop',
ApiServer_Restart = 'api-server:restart',
ApiServer_GetStatus = 'api-server:get-status',
ApiServer_Ready = 'api-server:ready',
// NOTE: This api is not be used.
ApiServer_GetConfig = 'api-server:get-config',
@@ -369,7 +375,8 @@ export enum IpcChannel {
CodeTools_RemoveCustomTerminalPath = 'code-tools:remove-custom-terminal-path',
// OCR
OCR_Ocr = 'ocr:ocr',
OCR_ocr = 'ocr:ocr',
OCR_ListProviders = 'ocr:list-providers',
// OVMS
Ovms_AddModel = 'ovms:add-model',
@@ -381,5 +388,21 @@ export enum IpcChannel {
Ovms_StopOVMS = 'ovms:stop-ovms',
// CherryAI
Cherryai_GetSignature = 'cherryai:get-signature'
Cherryai_GetSignature = 'cherryai:get-signature',
// Claude Code Plugins
ClaudeCodePlugin_ListAvailable = 'claudeCodePlugin:list-available',
ClaudeCodePlugin_Install = 'claudeCodePlugin:install',
ClaudeCodePlugin_Uninstall = 'claudeCodePlugin:uninstall',
ClaudeCodePlugin_ListInstalled = 'claudeCodePlugin:list-installed',
ClaudeCodePlugin_InvalidateCache = 'claudeCodePlugin:invalidate-cache',
ClaudeCodePlugin_ReadContent = 'claudeCodePlugin:read-content',
ClaudeCodePlugin_WriteContent = 'claudeCodePlugin:write-content',
// WebSocket
WebSocket_Start = 'webSocket:start',
WebSocket_Stop = 'webSocket:stop',
WebSocket_Status = 'webSocket:status',
WebSocket_SendFile = 'webSocket:send-file',
WebSocket_GetAllCandidates = 'webSocket:get-all-candidates'
}

View File

@@ -470,3 +470,6 @@ export const MACOS_TERMINALS_WITH_COMMANDS: TerminalConfigWithCommand[] = [
})
}
]
// resources/scripts should be maintained manually
export const HOME_CHERRY_DIR = '.cherrystudio'

View File

@@ -1,176 +0,0 @@
import type {
BuiltinOcrProvider,
BuiltinOcrProviderId,
OcrOvProvider,
OcrPpocrProvider,
OcrSystemProvider,
OcrTesseractProvider,
TesseractLangCode
} from '@types'
import type { TranslateLanguageCode } from '../../../src/renderer/src/types/translate'
export const tesseract: OcrTesseractProvider = {
id: 'tesseract',
name: 'Tesseract',
capabilities: {
image: true
},
config: {
langs: {
chi_sim: true,
chi_tra: true,
eng: true
},
enabled: false
}
} as const
export const systemOcr: OcrSystemProvider = {
id: 'system',
name: 'System',
capabilities: {
image: true
// pdf: true
},
config: {
langs: ['en-us'],
enabled: false
}
} as const satisfies OcrSystemProvider
export const ppocrOcr: OcrPpocrProvider = {
id: 'paddleocr',
name: 'PaddleOCR',
capabilities: {
image: true
// pdf: true
},
config: { apiUrl: '', enabled: false }
} as const
export const ovOcr: OcrOvProvider = {
id: 'ovocr',
name: 'Intel OV(NPU) OCR',
capabilities: {
image: true
// pdf: true
},
config: {
enabled: false
}
} as const satisfies OcrOvProvider
export const INITIAL_BUILTIN_OCR_PROVIDER_MAP = {
tesseract,
system: systemOcr,
paddleocr: ppocrOcr,
ovocr: ovOcr
} as const satisfies Record<BuiltinOcrProviderId, BuiltinOcrProvider>
export const BUILTIN_OCR_PROVIDERS: BuiltinOcrProvider[] = Object.values(INITIAL_BUILTIN_OCR_PROVIDER_MAP)
export const TESSERACT_LANG_MAP: Record<TranslateLanguageCode, TesseractLangCode> = {
'af-za': 'afr',
'am-et': 'amh',
'ar-sa': 'ara',
'as-in': 'asm',
'az-az': 'aze',
'az-cyrl-az': 'aze_cyrl',
'be-by': 'bel',
'bn-bd': 'ben',
'bo-cn': 'bod',
'bs-ba': 'bos',
'bg-bg': 'bul',
'ca-es': 'cat',
'ceb-ph': 'ceb',
'cs-cz': 'ces',
'zh-cn': 'chi_sim',
'zh-tw': 'chi_tra',
'chr-us': 'chr',
'cy-gb': 'cym',
'da-dk': 'dan',
'de-de': 'deu',
'dz-bt': 'dzo',
'el-gr': 'ell',
'en-us': 'eng',
'enm-gb': 'enm',
'eo-world': 'epo',
'et-ee': 'est',
'eu-es': 'eus',
'fa-ir': 'fas',
'fi-fi': 'fin',
'fr-fr': 'fra',
'frk-de': 'frk',
'frm-fr': 'frm',
'ga-ie': 'gle',
'gl-es': 'glg',
'grc-gr': 'grc',
'gu-in': 'guj',
'ht-ht': 'hat',
'he-il': 'heb',
'hi-in': 'hin',
'hr-hr': 'hrv',
'hu-hu': 'hun',
'iu-ca': 'iku',
'id-id': 'ind',
'is-is': 'isl',
'it-it': 'ita',
'ita-it': 'ita_old',
'jv-id': 'jav',
'ja-jp': 'jpn',
'kn-in': 'kan',
'ka-ge': 'kat',
'kat-ge': 'kat_old',
'kk-kz': 'kaz',
'km-kh': 'khm',
'ky-kg': 'kir',
'ko-kr': 'kor',
'ku-tr': 'kur',
'la-la': 'lao',
'la-va': 'lat',
'lv-lv': 'lav',
'lt-lt': 'lit',
'ml-in': 'mal',
'mr-in': 'mar',
'mk-mk': 'mkd',
'mt-mt': 'mlt',
'ms-my': 'msa',
'my-mm': 'mya',
'ne-np': 'nep',
'nl-nl': 'nld',
'no-no': 'nor',
'or-in': 'ori',
'pa-in': 'pan',
'pl-pl': 'pol',
'pt-pt': 'por',
'ps-af': 'pus',
'ro-ro': 'ron',
'ru-ru': 'rus',
'sa-in': 'san',
'si-lk': 'sin',
'sk-sk': 'slk',
'sl-si': 'slv',
'es-es': 'spa',
'spa-es': 'spa_old',
'sq-al': 'sqi',
'sr-rs': 'srp',
'sr-latn-rs': 'srp_latn',
'sw-tz': 'swa',
'sv-se': 'swe',
'syr-sy': 'syr',
'ta-in': 'tam',
'te-in': 'tel',
'tg-tj': 'tgk',
'tl-ph': 'tgl',
'th-th': 'tha',
'ti-er': 'tir',
'tr-tr': 'tur',
'ug-cn': 'uig',
'uk-ua': 'ukr',
'ur-pk': 'urd',
'uz-uz': 'uzb',
'uz-cyrl-uz': 'uzb_cyrl',
'vi-vn': 'vie',
'yi-us': 'yid'
}

View File

@@ -31,3 +31,16 @@ export type WebviewKeyEvent = {
shift: boolean
alt: boolean
}
export interface WebSocketStatusResponse {
isRunning: boolean
port?: number
ip?: string
clientConnected: boolean
}
export interface WebSocketCandidatesResponse {
host: string
interface: string
priority: number
}

View File

@@ -1,18 +1,5 @@
// NOTE: Types are defined inline in the schema for simplicity
// If needed, specific types can be imported from './apiModels'
import type {
CreateOcrProviderRequest,
CreateOcrProviderResponse,
GetOcrProviderResponse,
ListOcrProvidersQuery,
ListOcrProvidersResponse,
OcrProviderId,
ReplaceOcrProviderRequest,
ReplaceOcrProviderResponse,
UpdateOcrProviderRequest,
UpdateOcrProviderResponse
} from '@types'
import type { BodyForPath, ConcreteApiPaths, QueryParamsForPath, ResponseForPath } from './apiPaths'
import type { HttpMethod, PaginatedResponse, PaginationParams } from './apiTypes'
@@ -358,38 +345,6 @@ export interface ApiSchemas {
}>
}
}
'/ocr/providers': {
GET: {
query: ListOcrProvidersQuery
response: ListOcrProvidersResponse
}
POST: {
body: CreateOcrProviderRequest
response: CreateOcrProviderResponse
}
}
'/ocr/providers/:id': {
GET: {
params: { id: OcrProviderId }
response: GetOcrProviderResponse
}
PATCH: {
params: { id: OcrProviderId }
body: UpdateOcrProviderRequest
response: UpdateOcrProviderResponse
}
PUT: {
params: { id: OcrProviderId }
body: ReplaceOcrProviderRequest
response: ReplaceOcrProviderResponse
}
DELETE: {
params: { id: OcrProviderId }
response: void
}
}
}
/**

View File

@@ -351,8 +351,6 @@ export interface PreferenceSchemas {
'feature.translate.model_prompt': string
// redux/settings/targetLanguage
'feature.translate.target_language': string
// redux/ocr/imageProviderId
'ocr.settings.image_provider_id': string | null
// redux/shortcuts/shortcuts.exit_fullscreen
'shortcut.app.exit_fullscreen': Record<string, unknown>
// redux/shortcuts/shortcuts.search_message
@@ -614,7 +612,6 @@ export const DefaultPreferences: PreferenceSchemas = {
'feature.selection.trigger_mode': PreferenceTypes.SelectionTriggerMode.Selected,
'feature.translate.model_prompt': TRANSLATE_PROMPT,
'feature.translate.target_language': 'en-us',
'ocr.settings.image_provider_id': null,
'shortcut.app.exit_fullscreen': { editable: false, enabled: true, key: ['Escape'], system: true },
'shortcut.app.search_message': {
editable: true,

View File

@@ -1,2 +0,0 @@
export * from './json'
export * from './net'

View File

@@ -1,7 +0,0 @@
export function safeParseJson(text: string): unknown | null {
try {
return JSON.parse(text)
} catch {
return null
}
}

View File

@@ -1,17 +1,28 @@
import { fileURLToPath } from 'node:url'
import type { StorybookConfig } from '@storybook/react-vite'
import { dirname, resolve } from 'path'
const config: StorybookConfig = {
stories: ['../stories/components/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-docs', '@storybook/addon-themes'],
framework: '@storybook/react-vite',
addons: [getAbsolutePath('@storybook/addon-docs'), getAbsolutePath('@storybook/addon-themes')],
framework: getAbsolutePath('@storybook/react-vite'),
viteFinal: async (config) => {
const { mergeConfig } = await import('vite')
// 动态导入 @tailwindcss/vite 以避免 ESM/CJS 兼容性问题
const tailwindPlugin = (await import('@tailwindcss/vite')).default
return mergeConfig(config, {
plugins: [tailwindPlugin()]
plugins: [tailwindPlugin()],
resolve: {
alias: {
'@cherrystudio/ui': resolve('src')
}
}
})
}
}
export default config
function getAbsolutePath(value: string): any {
return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`)))
}

View File

@@ -4,6 +4,14 @@ import { withThemeByClassName } from '@storybook/addon-themes'
import type { Preview } from '@storybook/react'
const preview: Preview = {
parameters: {
backgrounds: {
options: {
light: { name: 'Light', value: 'hsla(0, 0%, 97%, 1)' },
dark: { name: 'Dark', value: 'hsla(240, 6%, 10%, 1)' }
}
}
},
decorators: [
withThemeByClassName({
themes: {

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,26 @@
# UI Component Library Migration Status
# Cherry Studio UI Migration Plan
## Overview
This document outlines the detailed plan for migrating Cherry Studio from antd + styled-components to shadcn/ui + Tailwind CSS. We will adopt a progressive migration strategy to ensure system stability and development efficiency, while gradually implementing UI refactoring in collaboration with UI designers.
## Migration Strategy
### Target Tech Stack
- **UI Component Library**: shadcn/ui (replacing antd and previously migrated HeroUI)
- **Styling Solution**: Tailwind CSS v4 (replacing styled-components)
- **Design System**: Custom CSS variable system (`--cs-*` namespace)
- **Theme System**: CSS variables + Tailwind CSS theme
### Migration Principles
1. **Backward Compatibility**: Old components continue working until new components are fully available
2. **Progressive Migration**: Migrate components one by one to avoid large-scale rewrites
3. **Feature Parity**: Ensure new components have all the functionality of old components
4. **Design Consistency**: Follow new design system specifications (see [README.md](./README.md))
5. **Performance Priority**: Optimize bundle size and rendering performance
6. **Designer Collaboration**: Work with UI designers for gradual component encapsulation and UI optimization
## Usage Example
@@ -24,115 +46,68 @@ function MyComponent() {
@packages/ui/
├── src/
│ ├── components/ # Main components directory
│ │ ├── base/ # Basic components (buttons, inputs, labels, etc.)
│ │ ├── display/ # Display components (cards, lists, tables, etc.)
│ │ ├── layout/ # Layout components (containers, grids, spacing, etc.)
│ │ ── icons/ # Icon components
│ │ ├── interactive/ # Interactive components (modals, tooltips, dropdowns, etc.)
│ │ └── composite/ # Composite components (made from multiple base components)
│ │ ├── primitives/ # Basic/primitive components (Avatar, ErrorBoundary, Selector, etc.)
│ │ │ └── shadcn-io/ # shadcn/ui components (dropzone, etc.)
│ │ ├── icons/ # Icon components (Icon, FileIcons, etc.)
│ │ ── composites/ # Composite components (CodeEditor, ListItem, etc.)
│ ├── hooks/ # Custom React Hooks
── types/ # TypeScript type definitions
── styles/ # Global styles and CSS variables
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions
│ └── index.ts # Main export file
```
### Component Classification Guide
When submitting PRs, please place components in the correct directory based on their function:
- **base**: Most basic UI elements like buttons, inputs, switches, labels, etc.
- **display**: Components for displaying content like cards, lists, tables, tabs, etc.
- **layout**: Components for page layout like containers, grid systems, dividers, etc.
- **primitives**: Basic and primitive UI elements, shadcn/ui components
- `Avatar`: Avatar components
- `ErrorBoundary`: Error boundary components
- `Selector`: Selection components
- `shadcn-io/`: Direct shadcn/ui components or adaptations
- **icons**: All icon-related components
- **interactive**: Components requiring user interaction like modals, drawers, tooltips, dropdowns, etc.
- **composite**: Composite components made from multiple base components
- `Icon`: Icon factory and basic icons
- `FileIcons`: File-specific icons
- Loading/spinner icons (SvgSpinners180Ring, ToolsCallingIcon, etc.)
- **composites**: Complex components made from multiple primitives
- `CodeEditor`: Code editing components
- `ListItem`: List item components
- `ThinkingEffect`: Animation components
- Form and interaction components (DraggableList, EditableNumber, etc.)
## Migration Overview
## Component Extraction Criteria
- **Total Components**: 236
- **Migrated**: 34
- **Refactored**: 18
- **Pending Migration**: 184
### Extraction Standards
## Component Status Table
1. **Usage Frequency**: Component is used in ≥ 3 places in the codebase
2. **Future Reusability**: Expected to be used in multiple scenarios in the future
3. **Business Complexity**: Component contains complex interaction logic or state management
4. **Maintenance Cost**: Centralized management can reduce maintenance overhead
5. **Design Consistency**: Components that require unified visual and interaction experience
6. **Test Coverage**: As common components, they facilitate unit test writing and maintenance
| Category | Component Name | Migration Status | Refactoring Status | Description |
| ----------------- | ------------------------- | ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **base** | | | | Base components |
| | CopyButton | ✅ | ✅ | Copy button |
| | CustomTag | ✅ | ✅ | Custom tag |
| | DividerWithText | ✅ | ✅ | Divider with text |
| | EmojiIcon | ✅ | ✅ | Emoji icon |
| | ErrorBoundary | ✅ | ✅ | Error boundary (decoupled via props) |
| | StatusTag | ✅ | ✅ | Unified status tag (merged ErrorTag, SuccessTag, WarnTag, InfoTag) |
| | IndicatorLight | ✅ | ✅ | Indicator light |
| | Spinner | ✅ | ✅ | Loading spinner |
| | TextBadge | ✅ | ✅ | Text badge |
| | CustomCollapse | ✅ | ✅ | Custom collapse panel |
| **display** | | | | Display components |
| | Ellipsis | ✅ | ✅ | Text ellipsis |
| | ExpandableText | ✅ | ✅ | Expandable text |
| | ThinkingEffect | ✅ | ✅ | Thinking effect animation |
| | EmojiAvatar | ✅ | ✅ | Emoji avatar |
| | ListItem | ✅ | ✅ | List item |
| | MaxContextCount | ✅ | ✅ | Max context count display |
| | ProviderAvatar | ✅ | ✅ | Provider avatar |
| | CodeViewer | ❌ | ❌ | Code viewer (external deps) |
| | OGCard | ❌ | ❌ | OG card |
| | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown renderer |
| | Preview/* | ❌ | ❌ | Preview components |
| **layout** | | | | Layout components |
| | HorizontalScrollContainer | ✅ | ❌ | Horizontal scroll container |
| | Scrollbar | ✅ | ❌ | Scrollbar |
| | Layout/* | ✅ | ✅ | Layout components |
| | Tab/* | ❌ | ❌ | Tab (Redux dependency) |
| | TopView | ❌ | ❌ | Top view (window.api dependency) |
| **icons** | | | | Icon components |
| | Icon | ✅ | ✅ | Icon factory function and predefined icons (merged CopyIcon, DeleteIcon, EditIcon, RefreshIcon, ResetIcon, ToolIcon, VisionIcon, WebSearchIcon, WrapIcon, UnWrapIcon, OcrIcon) |
| | FileIcons | ✅ | ❌ | File icons (FileSvgIcon, FilePngIcon) |
| | ReasoningIcon | ✅ | ❌ | Reasoning icon |
| | SvgSpinners180Ring | ✅ | ❌ | Spinner loading icon |
| | ToolsCallingIcon | ✅ | ❌ | Tools calling icon |
| **interactive** | | | | Interactive components |
| | InfoTooltip | ✅ | ❌ | Info tooltip |
| | HelpTooltip | ✅ | ❌ | Help tooltip |
| | WarnTooltip | ✅ | ❌ | Warning tooltip |
| | EditableNumber | ✅ | ❌ | Editable number |
| | InfoPopover | ✅ | ❌ | Info popover |
| | CollapsibleSearchBar | ✅ | ❌ | Collapsible search bar |
| | ImageToolButton | ✅ | ❌ | Image tool button |
| | DraggableList | ✅ | ❌ | Draggable list |
| | CodeEditor | ✅ | ❌ | Code editor |
| | EmojiPicker | ❌ | ❌ | Emoji picker (useTheme dependency) |
| | Selector | ✅ | ❌ | Selector (i18n dependency) |
| | ModelSelector | ❌ | ❌ | Model selector (Redux dependency) |
| | LanguageSelect | ❌ | ❌ | Language select |
| | TranslateButton | ❌ | ❌ | Translate button (window.api dependency) |
| **composite** | | | | Composite components |
| | - | - | - | No composite components yet |
| **Uncategorized** | | | | Components needing categorization |
| | Popups/* (16+ files) | ❌ | ❌ | Popup components (business coupled) |
| | RichEditor/* (30+ files) | ❌ | ❌ | Rich text editor |
| | MarkdownEditor/* | ❌ | ❌ | Markdown editor |
| | MinApp/* | ❌ | ❌ | Mini app (Redux dependency) |
| | Avatar/* | ❌ | ❌ | Avatar components |
| | ActionTools/* | ❌ | ❌ | Action tools |
| | CodeBlockView/* | ❌ | ❌ | Code block view (window.api dependency) |
| | ContextMenu | ❌ | ❌ | Context menu (Electron API) |
| | WindowControls | ❌ | ❌ | Window controls (Electron API) |
| | ErrorBoundary | ❌ | ❌ | Error boundary (window.api dependency) |
### Extraction Principles
- **Single Responsibility**: Each component should only handle one clear function
- **Highly Configurable**: Provide flexible configuration options through props
- **Backward Compatible**: New versions maintain API backward compatibility
- **Complete Documentation**: Provide clear API documentation and usage examples
- **Type Safety**: Use TypeScript to ensure type safety
### Cases Not Recommended for Extraction
- Simple display components used only on a single page
- Overly customized business logic components
- Components tightly coupled to specific data sources
## Migration Steps
### Phase 1: Copy Migration (Current Phase)
- Copy components as-is to @packages/ui
- Retain original dependencies (antd, styled-components, etc.)
- Add original path comment at file top
### Phase 2: Refactor and Optimize
- Remove antd dependencies, replace with HeroUI
- Remove styled-components, replace with Tailwind CSS
- Optimize component APIs and type definitions
| Phase | Status | Main Tasks | Description |
| --- | --- | --- | --- |
| **Phase 1** | ✅ **Completed** | **Design System Integration** | • Converted design tokens from todocss.css to tokens.css with `--cs-*` namespace<br>• Created theme.css mapping all design tokens to standard Tailwind classes<br>• Extended Tailwind with semantic spacing (5xs~8xl) and radius (4xs~3xl) systems<br>• Established two usage modes: full override and selective override<br>• Cleaned up main package's conflicting Shadcn theme definitions |
| **Phase 2** | ⏳ **To Start** | **Component Migration and Optimization** | • Filter components for migration based on extraction criteria<br>• Remove antd dependencies, replace with shadcn/ui<br>• Remove HeroUI dependencies, replace with shadcn/ui<br>• Remove styled-components, replace with Tailwind CSS + design system variables<br>• Optimize component APIs and type definitions |
| **Phase 3** | ⏳ **To Start** | **UI Refactoring and Optimization** | • Gradually implement UI refactoring with UI designers<br>• Ensure visual consistency and user experience<br>• Performance optimization and code quality improvement |
## Notes
@@ -143,9 +118,33 @@ When submitting PRs, please place components in the correct directory based on t
2. **Can migrate** but need decoupling later:
- Components using i18n (change i18n to props)
- Components using antd (replace with HeroUI later)
- Components using antd (replace with shadcn/ui later)
- Components using HeroUI (replace with shadcn/ui later)
3. **Submission Guidelines**:
- Each PR should focus on one category of components
- Ensure all migrated components are exported
- Update migration status in this document
- Follow component extraction criteria, only migrate qualified components
## Design System Integration
### CSS Variable System
- All design tokens use `--cs-*` namespace (e.g., `--cs-primary`, `--cs-red-500`)
- Complete color palette: 17 colors × 11 shades each
- Semantic spacing system: `5xs` through `8xl` (16 levels)
- Semantic radius system: `4xs` through `3xl` plus `round` (11 levels)
- Full light/dark mode support
- See [README.md](./README.md) for usage documentation
### Migration Priority Adjustment
1. **High Priority**: Basic components (buttons, inputs, tags, etc.)
2. **Medium Priority**: Display components (cards, lists, tables, etc.)
3. **Low Priority**: Composite components and business-coupled components
### UI Designer Collaboration
- All component designs need confirmation from UI designers
- Gradually implement UI refactoring to maintain visual consistency
- New components must comply with design system specifications

View File

@@ -2,54 +2,120 @@
Cherry Studio UI 组件库 - 为 Cherry Studio 设计的 React 组件集合
## 特性
## 特性
- 🎨 基于 Tailwind CSS 的现代化设计
- 📦 支持 ESM 和 CJS 格式
- 🔷 完整的 TypeScript 支持
- 🚀 可以作为 npm 包发布
- 🔧 开箱即用的常用 hooks 和工具函数
- 🎨 **设计系统**: 完整的 CherryStudio 设计令牌17种颜色 × 11个色阶 + 语义化主题)
- 🌓 **Dark Mode**: 开箱即用的深色模式支持
- 🚀 **Tailwind v4**: 基于最新 Tailwind CSS v4 构建
- 📦 **灵活导入**: 2种样式导入方式满足不同使用场景
- 🔷 **TypeScript**: 完整的类型定义和智能提示
- 🎯 **零冲突**: CSS 变量隔离,不覆盖用户主题
## 安装
---
## 🚀 快速开始
### 安装
```bash
# 安装组件库
npm install @cherrystudio/ui
# 安装必需的 peer dependencies
npm install @heroui/react framer-motion react react-dom tailwindcss
# peer dependencies
npm install framer-motion react react-dom tailwindcss
```
## 配置
### 两种使用方式
### 1. Tailwind CSS v4 配置
#### 方式 1完整覆盖 ✨
本组件库使用 Tailwind CSS v4配置方式已改变。在你的主 CSS 文件(如 `src/styles/tailwind.css`)中:
使用完整的 CherryStudio 设计系统,所有 Tailwind 类名映射到设计系统。
```css
/* app.css */
@import '@cherrystudio/ui/styles/theme.css';
```
**特点**
- ✅ 直接使用标准 Tailwind 类名(`bg-primary``bg-red-500``p-md``rounded-lg`
- ✅ 所有颜色使用设计师定义的值
- ✅ 扩展的 Spacing 系统(`p-5xs` ~ `p-8xl`,共 16 个语义化尺寸)
- ✅ 扩展的 Radius 系统(`rounded-4xs` ~ `rounded-3xl`,共 11 个圆角)
- ⚠️ 会完全覆盖 Tailwind 默认主题
**示例**
```tsx
<Button className="bg-primary text-red-500 p-md rounded-lg">
{/* bg-primary → 品牌色lime-500 */}
{/* text-red-500 → 设计师定义的红色 */}
{/* p-md → 2.5remspacing-md */}
{/* rounded-lg → 2.5remradius-lg */}
</Button>
{/* 扩展的工具类 */}
<div className="p-5xs"> (0.5rem)</div>
<div className="p-xs"> (1rem)</div>
<div className="p-sm"> (1.5rem)</div>
<div className="p-md"> (2.5rem)</div>
<div className="p-lg"> (3.5rem)</div>
<div className="p-xl"> (5rem)</div>
<div className="p-8xl"> (15rem)</div>
<div className="rounded-4xs"> (0.25rem)</div>
<div className="rounded-xs"> (1rem)</div>
<div className="rounded-md"> (2rem)</div>
<div className="rounded-xl"> (3rem)</div>
<div className="rounded-round"> (999px)</div>
```
#### 方式 2选择性覆盖 🎯
只导入设计令牌CSS 变量),手动选择要覆盖的部分。
```css
/* app.css */
@import 'tailwindcss';
@import '@cherrystudio/ui/styles/tokens.css';
/* 必须扫描组件库文件以提取类名 */
@source '../node_modules/@cherrystudio/ui/dist/**/*.{js,mjs}';
/* 你的应用源文件 */
@source './src/**/*.{js,ts,jsx,tsx}';
/*
* 如果你的应用直接使用 HeroUI 组件,需要添加:
* @source '../node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}';
* @plugin '@heroui/react/plugin';
*/
/* 自定义主题配置(可选) */
/* 只使用部分设计系统 */
@theme {
/* 你的主题扩展 */
--color-primary: var(--cs-primary); /* 使用 CS 的主色 */
--color-red-500: oklch(...); /* 使用自己的红色 */
--spacing-md: var(--cs-size-md); /* 使用 CS 的间距 */
--radius-lg: 1rem; /* 使用自己的圆角 */
}
```
注意Tailwind CSS v4 不再使用 `tailwind.config.js` 文件,所有配置都在 CSS 中完成。
**特点**
### 2. Provider 配置
- ✅ 不覆盖任何 Tailwind 默认主题
- ✅ 通过 CSS 变量访问所有设计令牌(`var(--cs-primary)``var(--cs-red-500)`
- ✅ 精细控制哪些使用 CS、哪些保持原样
- ✅ 适合有自己设计系统但想借用部分 CS 设计令牌的场景
**示例**
```tsx
{/* 通过 CSS 变量使用 CS 设计令牌 */}
<button style={{ backgroundColor: 'var(--cs-primary)' }}>
使 CherryStudio
</button>
{/* 保持原有的 Tailwind 类名不受影响 */}
<div className="bg-red-500">
使 Tailwind
</div>
{/* 可用的 CSS 变量 */}
<div style={{
color: 'var(--cs-primary)', // 品牌色
backgroundColor: 'var(--cs-red-500)', // 红色-500
padding: 'var(--cs-size-md)', // 间距
borderRadius: 'var(--cs-radius-lg)' // 圆角
}} />
```
### Provider 配置
在你的 App 根组件中添加 HeroUI Provider
@@ -94,9 +160,6 @@ function App() {
// 只导入组件
import { Button } from '@cherrystudio/ui/components'
// 只导入 hooks
import { useDebounce, useLocalStorage } from '@cherrystudio/ui/hooks'
// 只导入工具函数
import { cn, formatFileSize } from '@cherrystudio/ui/utils'
```

View File

@@ -13,7 +13,7 @@
"tailwind": {
"baseColor": "zinc",
"config": "",
"css": "src/styles/globals.css",
"css": "src/styles/theme.css",
"cssVariables": true,
"prefix": ""
},

View File

@@ -0,0 +1,15 @@
# Design Reference
本文件夹包含设计师提供的原始设计令牌文件,仅作为参考使用。
## 文件说明
### *.hsla.css
为hsla格式的色值
## 注意事项
⚠️ **请勿直接使用此文件夹中的文件**
- 这些文件仅供参考
- 实际使用请导入 `src/styles/` 中的文件

View File

@@ -0,0 +1,309 @@
/**
* Primitive Colors - Light Mode
* 基础色板 - 所有原始颜色定义
*/
:root {
/* Neutral */
--cs-neutral-50: hsla(0, 0%, 98%, 1);
--cs-neutral-100: hsla(0, 0%, 96%, 1);
--cs-neutral-200: hsla(0, 0%, 90%, 1);
--cs-neutral-300: hsla(0, 0%, 83%, 1);
--cs-neutral-400: hsla(0, 0%, 64%, 1);
--cs-neutral-500: hsla(0, 0%, 45%, 1);
--cs-neutral-600: hsla(215, 14%, 34%, 1);
--cs-neutral-700: hsla(0, 0%, 25%, 1);
--cs-neutral-800: hsla(0, 0%, 15%, 1);
--cs-neutral-900: hsla(0, 0%, 9%, 1);
--cs-neutral-950: hsla(0, 0%, 4%, 1);
/* Stone */
--cs-stone-50: hsla(60, 9%, 98%, 1);
--cs-stone-100: hsla(60, 5%, 96%, 1);
--cs-stone-200: hsla(20, 6%, 90%, 1);
--cs-stone-300: hsla(24, 6%, 83%, 1);
--cs-stone-400: hsla(24, 5%, 64%, 1);
--cs-stone-500: hsla(25, 5%, 45%, 1);
--cs-stone-600: hsla(33, 5%, 32%, 1);
--cs-stone-700: hsla(30, 6%, 25%, 1);
--cs-stone-800: hsla(12, 6%, 15%, 1);
--cs-stone-900: hsla(24, 10%, 10%, 1);
--cs-stone-950: hsla(20, 14%, 4%, 1);
/* Zinc */
--cs-zinc-50: hsla(0, 0%, 98%, 1);
--cs-zinc-100: hsla(240, 5%, 96%, 1);
--cs-zinc-200: hsla(240, 6%, 90%, 1);
--cs-zinc-300: hsla(240, 5%, 84%, 1);
--cs-zinc-400: hsla(240, 5%, 65%, 1);
--cs-zinc-500: hsla(240, 4%, 46%, 1);
--cs-zinc-600: hsla(240, 5%, 34%, 1);
--cs-zinc-700: hsla(240, 5%, 26%, 1);
--cs-zinc-800: hsla(240, 4%, 16%, 1);
--cs-zinc-900: hsla(240, 6%, 10%, 1);
--cs-zinc-950: hsla(240, 10%, 4%, 1);
/* Slate */
--cs-slate-50: hsla(210, 40%, 98%, 1);
--cs-slate-100: hsla(210, 40%, 96%, 1);
--cs-slate-200: hsla(214, 32%, 91%, 1);
--cs-slate-300: hsla(213, 27%, 84%, 1);
--cs-slate-400: hsla(215, 20%, 65%, 1);
--cs-slate-500: hsla(215, 16%, 47%, 1);
--cs-slate-600: hsla(215, 19%, 35%, 1);
--cs-slate-700: hsla(215, 25%, 27%, 1);
--cs-slate-800: hsla(217, 33%, 17%, 1);
--cs-slate-900: hsla(222, 47%, 11%, 1);
--cs-slate-950: hsla(229, 84%, 5%, 1);
/* Gray */
--cs-gray-50: hsla(210, 20%, 98%, 1);
--cs-gray-100: hsla(220, 14%, 96%, 1);
--cs-gray-200: hsla(220, 13%, 91%, 1);
--cs-gray-300: hsla(216, 12%, 84%, 1);
--cs-gray-400: hsla(218, 11%, 65%, 1);
--cs-gray-500: hsla(220, 9%, 46%, 1);
--cs-gray-600: hsla(0, 0%, 32%, 1);
--cs-gray-700: hsla(217, 19%, 27%, 1);
--cs-gray-800: hsla(215, 28%, 17%, 1);
--cs-gray-900: hsla(221, 39%, 11%, 1);
--cs-gray-950: hsla(224, 71%, 4%, 1);
/* Red */
--cs-red-50: hsla(0, 86%, 97%, 1);
--cs-red-100: hsla(0, 93%, 94%, 1);
--cs-red-200: hsla(0, 96%, 89%, 1);
--cs-red-300: hsla(0, 94%, 82%, 1);
--cs-red-400: hsla(0, 91%, 71%, 1);
--cs-red-500: hsla(0, 84%, 60%, 1);
--cs-red-600: hsla(0, 72%, 51%, 1);
--cs-red-700: hsla(0, 74%, 42%, 1);
--cs-red-800: hsla(0, 70%, 35%, 1);
--cs-red-900: hsla(0, 63%, 31%, 1);
--cs-red-950: hsla(0, 75%, 15%, 1);
/* Orange */
--cs-orange-50: hsla(33, 100%, 96%, 1);
--cs-orange-100: hsla(34, 100%, 92%, 1);
--cs-orange-200: hsla(32, 98%, 83%, 1);
--cs-orange-300: hsla(31, 97%, 72%, 1);
--cs-orange-400: hsla(27, 96%, 61%, 1);
--cs-orange-500: hsla(25, 95%, 53%, 1);
--cs-orange-600: hsla(21, 90%, 48%, 1);
--cs-orange-700: hsla(17, 88%, 40%, 1);
--cs-orange-800: hsla(15, 79%, 34%, 1);
--cs-orange-900: hsla(15, 75%, 28%, 1);
--cs-orange-950: hsla(13, 81%, 15%, 1);
/* Amber */
--cs-amber-50: hsla(48, 100%, 96%, 1);
--cs-amber-100: hsla(48, 96%, 89%, 1);
--cs-amber-200: hsla(48, 97%, 77%, 1);
--cs-amber-300: hsla(46, 97%, 65%, 1);
--cs-amber-400: hsla(43, 96%, 56%, 1);
--cs-amber-500: hsla(38, 92%, 50%, 1);
--cs-amber-600: hsla(32, 95%, 44%, 1);
--cs-amber-700: hsla(26, 90%, 37%, 1);
--cs-amber-800: hsla(23, 83%, 31%, 1);
--cs-amber-900: hsla(22, 78%, 26%, 1);
--cs-amber-950: hsla(21, 92%, 14%, 1);
/* Yellow */
--cs-yellow-50: hsla(55, 92%, 95%, 1);
--cs-yellow-100: hsla(55, 97%, 88%, 1);
--cs-yellow-200: hsla(53, 98%, 77%, 1);
--cs-yellow-300: hsla(50, 98%, 64%, 1);
--cs-yellow-400: hsla(48, 96%, 53%, 1);
--cs-yellow-500: hsla(45, 93%, 47%, 1);
--cs-yellow-600: hsla(41, 96%, 40%, 1);
--cs-yellow-700: hsla(35, 92%, 33%, 1);
--cs-yellow-800: hsla(32, 81%, 29%, 1);
--cs-yellow-900: hsla(28, 73%, 26%, 1);
--cs-yellow-950: hsla(26, 83%, 14%, 1);
/* Lime (品牌主色) */
--cs-lime-50: hsla(78, 92%, 95%, 1);
--cs-lime-100: hsla(80, 89%, 89%, 1);
--cs-lime-200: hsla(81, 88%, 80%, 1);
--cs-lime-300: hsla(82, 85%, 67%, 1);
--cs-lime-400: hsla(83, 78%, 55%, 1);
--cs-lime-500: hsla(84, 81%, 44%, 1);
--cs-lime-600: hsla(85, 85%, 35%, 1);
--cs-lime-700: hsla(86, 78%, 27%, 1);
--cs-lime-800: hsla(86, 69%, 23%, 1);
--cs-lime-900: hsla(88, 61%, 20%, 1);
--cs-lime-950: hsla(89, 80%, 10%, 1);
/* Green */
--cs-green-50: hsla(138, 76%, 97%, 1);
--cs-green-100: hsla(141, 84%, 93%, 1);
--cs-green-200: hsla(141, 79%, 85%, 1);
--cs-green-300: hsla(142, 77%, 73%, 1);
--cs-green-400: hsla(142, 69%, 58%, 1);
--cs-green-500: hsla(142, 71%, 45%, 1);
--cs-green-600: hsla(142, 76%, 36%, 1);
--cs-green-700: hsla(142, 72%, 29%, 1);
--cs-green-800: hsla(143, 64%, 24%, 1);
--cs-green-900: hsla(144, 61%, 20%, 1);
--cs-green-950: hsla(145, 80%, 10%, 1);
/* Emerald */
--cs-emerald-50: hsla(152, 81%, 96%, 1);
--cs-emerald-100: hsla(149, 80%, 90%, 1);
--cs-emerald-200: hsla(152, 76%, 80%, 1);
--cs-emerald-300: hsla(156, 72%, 67%, 1);
--cs-emerald-400: hsla(158, 64%, 52%, 1);
--cs-emerald-500: hsla(160, 84%, 39%, 1);
--cs-emerald-600: hsla(161, 94%, 30%, 1);
--cs-emerald-700: hsla(163, 94%, 24%, 1);
--cs-emerald-800: hsla(163, 88%, 20%, 1);
--cs-emerald-900: hsla(164, 86%, 16%, 1);
--cs-emerald-950: hsla(166, 91%, 9%, 1);
/* Teal */
--cs-teal-50: hsla(166, 76%, 97%, 1);
--cs-teal-100: hsla(167, 85%, 89%, 1);
--cs-teal-200: hsla(168, 84%, 78%, 1);
--cs-teal-300: hsla(171, 77%, 64%, 1);
--cs-teal-400: hsla(172, 66%, 50%, 1);
--cs-teal-500: hsla(173, 80%, 40%, 1);
--cs-teal-600: hsla(175, 84%, 32%, 1);
--cs-teal-700: hsla(175, 77%, 26%, 1);
--cs-teal-800: hsla(176, 69%, 22%, 1);
--cs-teal-900: hsla(176, 61%, 19%, 1);
--cs-teal-950: hsla(179, 84%, 10%, 1);
/* Cyan */
--cs-cyan-50: hsla(183, 100%, 96%, 1);
--cs-cyan-100: hsla(185, 96%, 90%, 1);
--cs-cyan-200: hsla(186, 94%, 82%, 1);
--cs-cyan-300: hsla(187, 92%, 69%, 1);
--cs-cyan-400: hsla(188, 86%, 53%, 1);
--cs-cyan-500: hsla(189, 94%, 43%, 1);
--cs-cyan-600: hsla(192, 91%, 36%, 1);
--cs-cyan-700: hsla(193, 82%, 31%, 1);
--cs-cyan-800: hsla(194, 70%, 27%, 1);
--cs-cyan-900: hsla(196, 64%, 24%, 1);
--cs-cyan-950: hsla(197, 79%, 15%, 1);
/* Sky */
--cs-sky-50: hsla(204, 100%, 97%, 1);
--cs-sky-100: hsla(204, 94%, 94%, 1);
--cs-sky-200: hsla(201, 94%, 86%, 1);
--cs-sky-300: hsla(199, 95%, 74%, 1);
--cs-sky-400: hsla(198, 93%, 60%, 1);
--cs-sky-500: hsla(199, 89%, 48%, 1);
--cs-sky-600: hsla(200, 98%, 39%, 1);
--cs-sky-700: hsla(201, 96%, 32%, 1);
--cs-sky-800: hsla(201, 90%, 27%, 1);
--cs-sky-900: hsla(202, 80%, 24%, 1);
--cs-sky-950: hsla(204, 80%, 16%, 1);
/* Blue */
--cs-blue-50: hsla(214, 100%, 97%, 1);
--cs-blue-100: hsla(214, 95%, 93%, 1);
--cs-blue-200: hsla(213, 97%, 87%, 1);
--cs-blue-300: hsla(212, 96%, 78%, 1);
--cs-blue-400: hsla(213, 94%, 68%, 1);
--cs-blue-500: hsla(217, 91%, 60%, 1);
--cs-blue-600: hsla(221, 83%, 53%, 1);
--cs-blue-700: hsla(224, 76%, 48%, 1);
--cs-blue-800: hsla(226, 71%, 40%, 1);
--cs-blue-900: hsla(224, 64%, 33%, 1);
--cs-blue-950: hsla(226, 57%, 21%, 1);
/* Indigo */
--cs-indigo-50: hsla(226, 100%, 97%, 1);
--cs-indigo-100: hsla(226, 100%, 94%, 1);
--cs-indigo-200: hsla(228, 96%, 89%, 1);
--cs-indigo-300: hsla(230, 94%, 82%, 1);
--cs-indigo-400: hsla(234, 89%, 74%, 1);
--cs-indigo-500: hsla(239, 84%, 67%, 1);
--cs-indigo-600: hsla(243, 75%, 59%, 1);
--cs-indigo-700: hsla(245, 58%, 51%, 1);
--cs-indigo-800: hsla(244, 55%, 41%, 1);
--cs-indigo-900: hsla(242, 47%, 34%, 1);
--cs-indigo-950: hsla(244, 47%, 20%, 1);
/* Violet */
--cs-violet-50: hsla(250, 100%, 98%, 1);
--cs-violet-100: hsla(251, 91%, 95%, 1);
--cs-violet-200: hsla(251, 95%, 92%, 1);
--cs-violet-300: hsla(253, 95%, 85%, 1);
--cs-violet-400: hsla(255, 92%, 76%, 1);
--cs-violet-500: hsla(258, 90%, 66%, 1);
--cs-violet-600: hsla(262, 83%, 58%, 1);
--cs-violet-700: hsla(263, 70%, 50%, 1);
--cs-violet-800: hsla(263, 69%, 42%, 1);
--cs-violet-900: hsla(264, 67%, 35%, 1);
--cs-violet-950: hsla(262, 78%, 23%, 1);
/* Purple */
--cs-purple-50: hsla(270, 100%, 98%, 1);
--cs-purple-100: hsla(269, 100%, 95%, 1);
--cs-purple-200: hsla(269, 100%, 92%, 1);
--cs-purple-300: hsla(269, 97%, 85%, 1);
--cs-purple-400: hsla(270, 95%, 75%, 1);
--cs-purple-500: hsla(271, 91%, 65%, 1);
--cs-purple-600: hsla(271, 81%, 56%, 1);
--cs-purple-700: hsla(272, 72%, 47%, 1);
--cs-purple-800: hsla(273, 67%, 39%, 1);
--cs-purple-900: hsla(274, 66%, 32%, 1);
--cs-purple-950: hsla(274, 87%, 21%, 1);
/* Fuchsia */
--cs-fuchsia-50: hsla(289, 100%, 98%, 1);
--cs-fuchsia-100: hsla(287, 100%, 95%, 1);
--cs-fuchsia-200: hsla(288, 96%, 91%, 1);
--cs-fuchsia-300: hsla(291, 93%, 83%, 1);
--cs-fuchsia-400: hsla(292, 91%, 73%, 1);
--cs-fuchsia-500: hsla(292, 84%, 61%, 1);
--cs-fuchsia-600: hsla(293, 69%, 49%, 1);
--cs-fuchsia-700: hsla(295, 72%, 40%, 1);
--cs-fuchsia-800: hsla(295, 70%, 33%, 1);
--cs-fuchsia-900: hsla(297, 64%, 28%, 1);
--cs-fuchsia-950: hsla(297, 90%, 16%, 1);
/* Pink */
--cs-pink-50: hsla(327, 73%, 97%, 1);
--cs-pink-100: hsla(326, 78%, 95%, 1);
--cs-pink-200: hsla(326, 85%, 90%, 1);
--cs-pink-300: hsla(327, 87%, 82%, 1);
--cs-pink-400: hsla(329, 86%, 70%, 1);
--cs-pink-500: hsla(330, 81%, 60%, 1);
--cs-pink-600: hsla(333, 71%, 51%, 1);
--cs-pink-700: hsla(335, 78%, 42%, 1);
--cs-pink-800: hsla(336, 74%, 35%, 1);
--cs-pink-900: hsla(336, 69%, 30%, 1);
--cs-pink-950: hsla(336, 84%, 17%, 1);
/* Rose */
--cs-rose-50: hsla(356, 100%, 97%, 1);
--cs-rose-100: hsla(356, 100%, 95%, 1);
--cs-rose-200: hsla(353, 96%, 90%, 1);
--cs-rose-300: hsla(353, 96%, 82%, 1);
--cs-rose-400: hsla(351, 95%, 71%, 1);
--cs-rose-500: hsla(350, 89%, 60%, 1);
--cs-rose-600: hsla(347, 77%, 50%, 1);
--cs-rose-700: hsla(345, 83%, 41%, 1);
--cs-rose-800: hsla(343, 80%, 35%, 1);
--cs-rose-900: hsla(342, 75%, 30%, 1);
--cs-rose-950: hsla(343, 88%, 16%, 1);
/* Black & White */
--cs-black: hsla(0, 0%, 0%, 1);
--cs-white: hsla(0, 0%, 100%, 1);
/* Brand (Cherry Studio 品牌专属色) */
--cs-brand-50: hsla(132, 64%, 97%, 1);
--cs-brand-100: hsla(132, 64%, 93%, 1);
--cs-brand-200: hsla(132, 64%, 85%, 1);
--cs-brand-300: hsla(132, 64%, 73%, 1);
--cs-brand-400: hsla(132, 64%, 63%, 1);
--cs-brand-500: hsla(132, 64%, 53%, 1);
--cs-brand-600: hsla(132, 64%, 43%, 1);
--cs-brand-700: hsla(132, 64%, 33%, 1);
--cs-brand-800: hsla(132, 64%, 23%, 1);
--cs-brand-900: hsla(132, 64%, 13%, 1);
--cs-brand-950: hsla(132, 64%, 8%, 1);
}

View File

@@ -0,0 +1,81 @@
/**
* Semantic Colors - Light Mode
* 语义化颜色 - 基于 Primitive Colors 的语义化映射
*/
:root {
/* Brand Colors */
--cs-primary: var(--cs-brand-500);
--cs-primary-hover: var(--cs-brand-300);
--cs-destructive: var(--cs-red-500);
--cs-destructive-hover: var(--cs-red-400);
--cs-success: var(--cs-green-500);
--cs-warning: var(--cs-amber-500);
/* Background & Foreground */
--cs-background: var(--cs-zinc-50);
--cs-background-subtle: hsla(0, 0%, 0%, 0.02);
--cs-foreground: hsla(0, 0%, 0%, 0.9);
--cs-foreground-secondary: hsla(0, 0%, 0%, 0.6);
--cs-foreground-muted: hsla(0, 0%, 0%, 0.4);
/* Card & Popover */
--cs-card: var(--cs-white);
--cs-popover: var(--cs-white);
/* Border */
--cs-border: hsla(0, 0%, 0%, 0.1);
--cs-border-hover: hsla(0, 0%, 0%, 0.2);
--cs-border-active: hsla(0, 0%, 0%, 0.3);
/* Ring (Focus) */
--cs-ring: color-mix(in srgb, var(--cs-primary) 40%, transparent);
/* UI Element Colors */
--cs-secondary: hsla(0, 0%, 0%, 0.05); /* Secondary Button Background */
--cs-secondary-hover: hsla(0, 0%, 0%, 0.85);
--cs-secondary-active: hsla(0, 0%, 0%, 0.7);
--cs-muted: hsla(0, 0%, 0%, 0.05); /* Muted/Subtle Background */
--cs-accent: hsla(0, 0%, 0%, 0.05); /* Accent Background */
--cs-ghost-hover: hsla(0, 0%, 0%, 0.05); /* Ghost Button Hover */
--cs-ghost-active: hsla(0, 0%, 0%, 0.1); /* Ghost Button Active */
/* Sidebar */
--cs-sidebar: var(--cs-white);
--cs-sidebar-accent: hsla(0, 0%, 0%, 0.05);
}
/* Dark Mode */
.dark {
/* Background & Foreground */
--cs-background: var(--cs-zinc-900);
--cs-background-subtle: hsla(0, 0%, 100%, 0.02);
--cs-foreground: hsla(0, 0%, 100%, 0.9);
--cs-foreground-secondary: hsla(0, 0%, 100%, 0.6);
--cs-foreground-muted: hsla(0, 0%, 100%, 0.4);
/* Card & Popover */
--cs-card: var(--cs-black);
--cs-popover: var(--cs-black);
/* Border */
--cs-border: hsla(0, 0%, 100%, 0.1);
--cs-border-hover: hsla(0, 0%, 100%, 0.2);
--cs-border-active: hsla(0, 0%, 100%, 0.3);
/* Ring (Focus) - 保持不变 */
--cs-ring: hsla(84, 81%, 44%, 0.4);
/* UI Element Colors - Dark Mode */
--cs-secondary: hsla(0, 0%, 100%, 0.1); /* Secondary Button Background */
--cs-secondary-hover: hsla(0, 0%, 100%, 0.2);
--cs-secondary-active: hsla(0, 0%, 100%, 0.25);
--cs-muted: hsla(0, 0%, 100%, 0.1); /* Muted/Subtle Background */
--cs-accent: hsla(0, 0%, 100%, 0.1); /* Accent Background */
--cs-ghost-hover: hsla(0, 0%, 100%, 0.1); /* Ghost Button Hover */
--cs-ghost-active: hsla(0, 0%, 100%, 0.15); /* Ghost Button Active */
/* Sidebar */
--cs-sidebar: var(--cs-black);
--cs-sidebar-accent: hsla(0, 0%, 100%, 0.1);
}

View File

@@ -0,0 +1,55 @@
/**
* Status Colors - Light Mode & Dark Mode
* 状态颜色 - Error, Success, Warning
*/
:root {
/* Status Colors - Error */
--cs-error-base: var(--cs-red-500); /* #ef4444 */
--cs-error-text: var(--cs-red-800); /* #991b1b */
--cs-error-bg: var(--cs-red-50); /* #fef2f2 */
--cs-error-text-hover: var(--cs-red-700); /* #b91c1c */
--cs-error-bg-hover: var(--cs-red-100); /* #fee2e2 */
--cs-error-border: var(--cs-red-200); /* #fecaca */
--cs-error-border-hover: var(--cs-red-300); /* #fca5a5 */
--cs-error-active: var(--cs-red-600); /* #dc2626 */
/* Status Colors - Success */
--cs-success-base: var(--cs-green-500); /* #22c55e */
--cs-success-text-hover: var(--cs-green-700); /* #15803d */
--cs-success-bg: var(--cs-green-50); /* #f0fdf4 */
--cs-success-bg-hover: var(--cs-green-200); /* #bbf7d0 */
/* Status Colors - Warning */
--cs-warning-base: var(--cs-amber-400); /* #fbbf24 */
--cs-warning-text-hover: var(--cs-amber-700); /* #b45309 */
--cs-warning-bg: var(--cs-amber-50); /* #fffbeb */
--cs-warning-bg-hover: var(--cs-amber-100); /* #fef3c7 */
--cs-warning-active: var(--cs-amber-600); /* #d97706 */
}
/* Dark Mode */
.dark {
/* Status Colors - Error (Dark Mode) */
--cs-error-base: var(--cs-red-400); /* #f87171 */
--cs-error-text: var(--cs-red-100); /* #fee2e2 */
--cs-error-bg: var(--cs-red-900); /* #7f1d1d */
--cs-error-text-hover: var(--cs-red-200); /* #fecaca */
--cs-error-bg-hover: var(--cs-red-800); /* #991b1b */
--cs-error-border: var(--cs-red-700); /* #b91c1c */
--cs-error-border-hover: var(--cs-red-600); /* #dc2626 */
--cs-error-active: var(--cs-red-300); /* #fca5a5 */
/* Status Colors - Success (Dark Mode) */
--cs-success-base: var(--cs-green-400); /* #4ade80 */
--cs-success-text-hover: var(--cs-green-200); /* #bbf7d0 */
--cs-success-bg: var(--cs-green-900); /* #14532d */
--cs-success-bg-hover: var(--cs-green-800); /* #166534 */
/* Status Colors - Warning (Dark Mode) */
--cs-warning-base: var(--cs-amber-400); /* #fbbf24 */
--cs-warning-text-hover: var(--cs-amber-200); /* #fde68a */
--cs-warning-bg: var(--cs-amber-900); /* #78350f */
--cs-warning-bg-hover: var(--cs-amber-800); /* #92400e */
--cs-warning-active: var(--cs-amber-600); /* #d97706 */
}

View File

@@ -0,0 +1,450 @@
/**
* Generated from Design Tokens
*
* ⚠️ DO NOT EDIT DIRECTLY!
* This file is auto-generated from tokens/ directory.
* To make changes, edit files in tokens/ and run: npm run tokens:build
*
* Generated on: 2025-11-07T08:56:09.444Z
*/
@theme {
/* ==================== */
/* Primitive Colors */
/* ==================== */
--color-neutral-50: hsla(0, 0%, 98%, 1);
--color-neutral-100: hsla(0, 0%, 96%, 1);
--color-neutral-200: hsla(0, 0%, 90%, 1);
--color-neutral-300: hsla(0, 0%, 83%, 1);
--color-neutral-400: hsla(0, 0%, 64%, 1);
--color-neutral-500: hsla(0, 0%, 45%, 1);
--color-neutral-600: hsla(215, 14%, 34%, 1);
--color-neutral-700: hsla(0, 0%, 25%, 1);
--color-neutral-800: hsla(0, 0%, 15%, 1);
--color-neutral-900: hsla(0, 0%, 9%, 1);
--color-neutral-950: hsla(0, 0%, 4%, 1);
--color-stone-50: hsla(60, 9%, 98%, 1);
--color-stone-100: hsla(60, 5%, 96%, 1);
--color-stone-200: hsla(20, 6%, 90%, 1);
--color-stone-300: hsla(24, 6%, 83%, 1);
--color-stone-400: hsla(24, 5%, 64%, 1);
--color-stone-500: hsla(25, 5%, 45%, 1);
--color-stone-600: hsla(33, 5%, 32%, 1);
--color-stone-700: hsla(30, 6%, 25%, 1);
--color-stone-800: hsla(12, 6%, 15%, 1);
--color-stone-900: hsla(24, 10%, 10%, 1);
--color-stone-950: hsla(20, 14%, 4%, 1);
--color-zinc-50: hsla(0, 0%, 98%, 1);
--color-zinc-100: hsla(240, 5%, 96%, 1);
--color-zinc-200: hsla(240, 6%, 90%, 1);
--color-zinc-300: hsla(240, 5%, 84%, 1);
--color-zinc-400: hsla(240, 5%, 65%, 1);
--color-zinc-500: hsla(240, 4%, 46%, 1);
--color-zinc-600: hsla(240, 5%, 34%, 1);
--color-zinc-700: hsla(240, 5%, 26%, 1);
--color-zinc-800: hsla(240, 4%, 16%, 1);
--color-zinc-900: hsla(240, 6%, 10%, 1);
--color-zinc-950: hsla(240, 10%, 4%, 1);
--color-slate-50: hsla(210, 40%, 98%, 1);
--color-slate-100: hsla(210, 40%, 96%, 1);
--color-slate-200: hsla(214, 32%, 91%, 1);
--color-slate-300: hsla(213, 27%, 84%, 1);
--color-slate-400: hsla(215, 20%, 65%, 1);
--color-slate-500: hsla(215, 16%, 47%, 1);
--color-slate-600: hsla(215, 19%, 35%, 1);
--color-slate-700: hsla(215, 25%, 27%, 1);
--color-slate-800: hsla(217, 33%, 17%, 1);
--color-slate-900: hsla(222, 47%, 11%, 1);
--color-slate-950: hsla(229, 84%, 5%, 1);
--color-gray-50: hsla(210, 20%, 98%, 1);
--color-gray-100: hsla(220, 14%, 96%, 1);
--color-gray-200: hsla(220, 13%, 91%, 1);
--color-gray-300: hsla(216, 12%, 84%, 1);
--color-gray-400: hsla(218, 11%, 65%, 1);
--color-gray-500: hsla(220, 9%, 46%, 1);
--color-gray-600: hsla(0, 0%, 32%, 1);
--color-gray-700: hsla(217, 19%, 27%, 1);
--color-gray-800: hsla(215, 28%, 17%, 1);
--color-gray-900: hsla(221, 39%, 11%, 1);
--color-gray-950: hsla(224, 71%, 4%, 1);
--color-red-50: hsla(0, 86%, 97%, 1);
--color-red-100: hsla(0, 93%, 94%, 1);
--color-red-200: hsla(0, 96%, 89%, 1);
--color-red-300: hsla(0, 94%, 82%, 1);
--color-red-400: hsla(0, 91%, 71%, 1);
--color-red-500: hsla(0, 84%, 60%, 1);
--color-red-600: hsla(0, 72%, 51%, 1);
--color-red-700: hsla(0, 74%, 42%, 1);
--color-red-800: hsla(0, 70%, 35%, 1);
--color-red-900: hsla(0, 63%, 31%, 1);
--color-red-950: hsla(0, 75%, 15%, 1);
--color-orange-50: hsla(33, 100%, 96%, 1);
--color-orange-100: hsla(34, 100%, 92%, 1);
--color-orange-200: hsla(32, 98%, 83%, 1);
--color-orange-300: hsla(31, 97%, 72%, 1);
--color-orange-400: hsla(27, 96%, 61%, 1);
--color-orange-500: hsla(25, 95%, 53%, 1);
--color-orange-600: hsla(21, 90%, 48%, 1);
--color-orange-700: hsla(17, 88%, 40%, 1);
--color-orange-800: hsla(15, 79%, 34%, 1);
--color-orange-900: hsla(15, 75%, 28%, 1);
--color-orange-950: hsla(13, 81%, 15%, 1);
--color-amber-50: hsla(48, 100%, 96%, 1);
--color-amber-100: hsla(48, 96%, 89%, 1);
--color-amber-200: hsla(48, 97%, 77%, 1);
--color-amber-300: hsla(46, 97%, 65%, 1);
--color-amber-400: hsla(43, 96%, 56%, 1);
--color-amber-500: hsla(38, 92%, 50%, 1);
--color-amber-600: hsla(32, 95%, 44%, 1);
--color-amber-700: hsla(26, 90%, 37%, 1);
--color-amber-800: hsla(23, 83%, 31%, 1);
--color-amber-900: hsla(22, 78%, 26%, 1);
--color-amber-950: hsla(21, 92%, 14%, 1);
--color-yellow-50: hsla(55, 92%, 95%, 1);
--color-yellow-100: hsla(55, 97%, 88%, 1);
--color-yellow-200: hsla(53, 98%, 77%, 1);
--color-yellow-300: hsla(50, 98%, 64%, 1);
--color-yellow-400: hsla(48, 96%, 53%, 1);
--color-yellow-500: hsla(45, 93%, 47%, 1);
--color-yellow-600: hsla(41, 96%, 40%, 1);
--color-yellow-700: hsla(35, 92%, 33%, 1);
--color-yellow-800: hsla(32, 81%, 29%, 1);
--color-yellow-900: hsla(28, 73%, 26%, 1);
--color-yellow-950: hsla(26, 83%, 14%, 1);
--color-lime-50: hsla(78, 92%, 95%, 1);
--color-lime-100: hsla(80, 89%, 89%, 1);
--color-lime-200: hsla(81, 88%, 80%, 1);
--color-lime-300: hsla(82, 85%, 67%, 1);
--color-lime-400: hsla(83, 78%, 55%, 1);
--color-lime-500: hsla(84, 81%, 44%, 1);
--color-lime-600: hsla(85, 85%, 35%, 1);
--color-lime-700: hsla(86, 78%, 27%, 1);
--color-lime-800: hsla(86, 69%, 23%, 1);
--color-lime-900: hsla(88, 61%, 20%, 1);
--color-lime-950: hsla(89, 80%, 10%, 1);
--color-green-50: hsla(138, 76%, 97%, 1);
--color-green-100: hsla(141, 84%, 93%, 1);
--color-green-200: hsla(141, 79%, 85%, 1);
--color-green-300: hsla(142, 77%, 73%, 1);
--color-green-400: hsla(142, 69%, 58%, 1);
--color-green-500: hsla(142, 71%, 45%, 1);
--color-green-600: hsla(142, 76%, 36%, 1);
--color-green-700: hsla(142, 72%, 29%, 1);
--color-green-800: hsla(143, 64%, 24%, 1);
--color-green-900: hsla(144, 61%, 20%, 1);
--color-green-950: hsla(145, 80%, 10%, 1);
--color-emerald-50: hsla(152, 81%, 96%, 1);
--color-emerald-100: hsla(149, 80%, 90%, 1);
--color-emerald-200: hsla(152, 76%, 80%, 1);
--color-emerald-300: hsla(156, 72%, 67%, 1);
--color-emerald-400: hsla(158, 64%, 52%, 1);
--color-emerald-500: hsla(160, 84%, 39%, 1);
--color-emerald-600: hsla(161, 94%, 30%, 1);
--color-emerald-700: hsla(163, 94%, 24%, 1);
--color-emerald-800: hsla(163, 88%, 20%, 1);
--color-emerald-900: hsla(164, 86%, 16%, 1);
--color-emerald-950: hsla(166, 91%, 9%, 1);
--color-teal-50: hsla(166, 76%, 97%, 1);
--color-teal-100: hsla(167, 85%, 89%, 1);
--color-teal-200: hsla(168, 84%, 78%, 1);
--color-teal-300: hsla(171, 77%, 64%, 1);
--color-teal-400: hsla(172, 66%, 50%, 1);
--color-teal-500: hsla(173, 80%, 40%, 1);
--color-teal-600: hsla(175, 84%, 32%, 1);
--color-teal-700: hsla(175, 77%, 26%, 1);
--color-teal-800: hsla(176, 69%, 22%, 1);
--color-teal-900: hsla(176, 61%, 19%, 1);
--color-teal-950: hsla(179, 84%, 10%, 1);
--color-cyan-50: hsla(183, 100%, 96%, 1);
--color-cyan-100: hsla(185, 96%, 90%, 1);
--color-cyan-200: hsla(186, 94%, 82%, 1);
--color-cyan-300: hsla(187, 92%, 69%, 1);
--color-cyan-400: hsla(188, 86%, 53%, 1);
--color-cyan-500: hsla(189, 94%, 43%, 1);
--color-cyan-600: hsla(192, 91%, 36%, 1);
--color-cyan-700: hsla(193, 82%, 31%, 1);
--color-cyan-800: hsla(194, 70%, 27%, 1);
--color-cyan-900: hsla(196, 64%, 24%, 1);
--color-cyan-950: hsla(197, 79%, 15%, 1);
--color-sky-50: hsla(204, 100%, 97%, 1);
--color-sky-100: hsla(204, 94%, 94%, 1);
--color-sky-200: hsla(201, 94%, 86%, 1);
--color-sky-300: hsla(199, 95%, 74%, 1);
--color-sky-400: hsla(198, 93%, 60%, 1);
--color-sky-500: hsla(199, 89%, 48%, 1);
--color-sky-600: hsla(200, 98%, 39%, 1);
--color-sky-700: hsla(201, 96%, 32%, 1);
--color-sky-800: hsla(201, 90%, 27%, 1);
--color-sky-900: hsla(202, 80%, 24%, 1);
--color-sky-950: hsla(204, 80%, 16%, 1);
--color-blue-50: hsla(214, 100%, 97%, 1);
--color-blue-100: hsla(214, 95%, 93%, 1);
--color-blue-200: hsla(213, 97%, 87%, 1);
--color-blue-300: hsla(212, 96%, 78%, 1);
--color-blue-400: hsla(213, 94%, 68%, 1);
--color-blue-500: hsla(217, 91%, 60%, 1);
--color-blue-600: hsla(221, 83%, 53%, 1);
--color-blue-700: hsla(224, 76%, 48%, 1);
--color-blue-800: hsla(226, 71%, 40%, 1);
--color-blue-900: hsla(224, 64%, 33%, 1);
--color-blue-950: hsla(226, 57%, 21%, 1);
--color-indigo-50: hsla(226, 100%, 97%, 1);
--color-indigo-100: hsla(226, 100%, 94%, 1);
--color-indigo-200: hsla(228, 96%, 89%, 1);
--color-indigo-300: hsla(230, 94%, 82%, 1);
--color-indigo-400: hsla(234, 89%, 74%, 1);
--color-indigo-500: hsla(239, 84%, 67%, 1);
--color-indigo-600: hsla(243, 75%, 59%, 1);
--color-indigo-700: hsla(245, 58%, 51%, 1);
--color-indigo-800: hsla(244, 55%, 41%, 1);
--color-indigo-900: hsla(242, 47%, 34%, 1);
--color-indigo-950: hsla(244, 47%, 20%, 1);
--color-violet-50: hsla(250, 100%, 98%, 1);
--color-violet-100: hsla(251, 91%, 95%, 1);
--color-violet-200: hsla(251, 95%, 92%, 1);
--color-violet-300: hsla(253, 95%, 85%, 1);
--color-violet-400: hsla(255, 92%, 76%, 1);
--color-violet-500: hsla(258, 90%, 66%, 1);
--color-violet-600: hsla(262, 83%, 58%, 1);
--color-violet-700: hsla(263, 70%, 50%, 1);
--color-violet-800: hsla(263, 69%, 42%, 1);
--color-violet-900: hsla(264, 67%, 35%, 1);
--color-violet-950: hsla(262, 78%, 23%, 1);
--color-purple-50: hsla(270, 100%, 98%, 1);
--color-purple-100: hsla(269, 100%, 95%, 1);
--color-purple-200: hsla(269, 100%, 92%, 1);
--color-purple-300: hsla(269, 97%, 85%, 1);
--color-purple-400: hsla(270, 95%, 75%, 1);
--color-purple-500: hsla(271, 91%, 65%, 1);
--color-purple-600: hsla(271, 81%, 56%, 1);
--color-purple-700: hsla(272, 72%, 47%, 1);
--color-purple-800: hsla(273, 67%, 39%, 1);
--color-purple-900: hsla(274, 66%, 32%, 1);
--color-purple-950: hsla(274, 87%, 21%, 1);
--color-fuchsia-50: hsla(289, 100%, 98%, 1);
--color-fuchsia-100: hsla(287, 100%, 95%, 1);
--color-fuchsia-200: hsla(288, 96%, 91%, 1);
--color-fuchsia-300: hsla(291, 93%, 83%, 1);
--color-fuchsia-400: hsla(292, 91%, 73%, 1);
--color-fuchsia-500: hsla(292, 84%, 61%, 1);
--color-fuchsia-600: hsla(293, 69%, 49%, 1);
--color-fuchsia-700: hsla(295, 72%, 40%, 1);
--color-fuchsia-800: hsla(295, 70%, 33%, 1);
--color-fuchsia-900: hsla(297, 64%, 28%, 1);
--color-fuchsia-950: hsla(297, 90%, 16%, 1);
--color-pink-50: hsla(327, 73%, 97%, 1);
--color-pink-100: hsla(326, 78%, 95%, 1);
--color-pink-200: hsla(326, 85%, 90%, 1);
--color-pink-300: hsla(327, 87%, 82%, 1);
--color-pink-400: hsla(329, 86%, 70%, 1);
--color-pink-500: hsla(330, 81%, 60%, 1);
--color-pink-600: hsla(333, 71%, 51%, 1);
--color-pink-700: hsla(335, 78%, 42%, 1);
--color-pink-800: hsla(336, 74%, 35%, 1);
--color-pink-900: hsla(336, 69%, 30%, 1);
--color-pink-950: hsla(336, 84%, 17%, 1);
--color-rose-50: hsla(356, 100%, 97%, 1);
--color-rose-100: hsla(356, 100%, 95%, 1);
--color-rose-200: hsla(353, 96%, 90%, 1);
--color-rose-300: hsla(353, 96%, 82%, 1);
--color-rose-400: hsla(351, 95%, 71%, 1);
--color-rose-500: hsla(350, 89%, 60%, 1);
--color-rose-600: hsla(347, 77%, 50%, 1);
--color-rose-700: hsla(345, 83%, 41%, 1);
--color-rose-800: hsla(343, 80%, 35%, 1);
--color-rose-900: hsla(342, 75%, 30%, 1);
--color-rose-950: hsla(343, 88%, 16%, 1);
--color-brand-50: hsla(132, 64%, 97%, 1);
--color-brand-100: hsla(132, 64%, 93%, 1);
--color-brand-200: hsla(132, 64%, 85%, 1);
--color-brand-300: hsla(132, 64%, 73%, 1);
--color-brand-400: hsla(132, 64%, 63%, 1);
--color-brand-500: hsla(132, 64%, 53%, 1);
--color-brand-600: hsla(132, 64%, 43%, 1);
--color-brand-700: hsla(132, 64%, 33%, 1);
--color-brand-800: hsla(132, 64%, 23%, 1);
--color-brand-900: hsla(132, 64%, 13%, 1);
--color-brand-950: hsla(132, 64%, 8%, 1);
/* ==================== */
/* Semantic Colors */
/* ==================== */
--color-primary: hsla(132, 64%, 53%, 1);
--color-primary-hover: hsla(132, 64%, 73%, 1);
--color-destructive: hsla(0, 84%, 60%, 1);
--color-destructive-hover: hsla(0, 91%, 71%, 1);
--color-background: hsla(0, 0%, 98%, 1);
--color-background-subtle: hsla(0, 0%, 0%, 0.02);
--color-foreground: hsla(0, 0%, 0%, 0.9);
--color-foreground-secondary: hsla(0, 0%, 0%, 0.6);
--color-foreground-muted: hsla(0, 0%, 0%, 0.4);
--color-card: hsla(0, 0%, 100%, 1);
--color-popover: hsla(0, 0%, 100%, 1);
--color-border: hsla(0, 0%, 0%, 0.1);
--color-border-hover: hsla(0, 0%, 0%, 0.2);
--color-border-active: hsla(0, 0%, 0%, 0.3);
--color-ring: color-mix(in srgb, hsla(132, 64%, 53%, 1) 40%, transparent);
--color-secondary: hsla(0, 0%, 0%, 0.05);
--color-secondary-hover: hsla(0, 0%, 0%, 0.85);
--color-secondary-active: hsla(0, 0%, 0%, 0.7);
--color-muted: hsla(0, 0%, 0%, 0.05);
--color-accent: hsla(0, 0%, 0%, 0.05);
--color-ghost-hover: hsla(0, 0%, 0%, 0.05);
--color-ghost-active: hsla(0, 0%, 0%, 0.1);
--color-sidebar: hsla(0, 0%, 100%, 1);
--color-sidebar-accent: hsla(0, 0%, 0%, 0.05);
--color-border-width-sm: 1px;
--color-border-width-md: 2px;
--color-border-width-lg: 3px;
/* ==================== */
/* Status Colors */
/* ==================== */
--color-error-base: hsla(0, 84%, 60%, 1);
--color-error-text: hsla(0, 70%, 35%, 1);
--color-error-bg: hsla(0, 86%, 97%, 1);
--color-error-text-hover: hsla(0, 74%, 42%, 1);
--color-error-bg-hover: hsla(0, 93%, 94%, 1);
--color-error-border: hsla(0, 96%, 89%, 1);
--color-error-border-hover: hsla(0, 94%, 82%, 1);
--color-error-active: hsla(0, 72%, 51%, 1);
--color-success-base: hsla(142, 71%, 45%, 1);
--color-success-text-hover: hsla(142, 72%, 29%, 1);
--color-success-bg: hsla(138, 76%, 97%, 1);
--color-success-bg-hover: hsla(141, 79%, 85%, 1);
--color-warning-base: hsla(43, 96%, 56%, 1);
--color-warning-text-hover: hsla(26, 90%, 37%, 1);
--color-warning-bg: hsla(48, 100%, 96%, 1);
--color-warning-bg-hover: hsla(48, 96%, 89%, 1);
--color-warning-active: hsla(32, 95%, 44%, 1);
/* ==================== */
/* Spacing */
/* ==================== */
--spacing-5xs: 0.25rem;
--spacing-4xs: 0.5rem;
--spacing-3xs: 0.75rem;
--spacing-2xs: 1rem;
--spacing-xs: 1.5rem;
--spacing-sm: 2rem;
--spacing-md: 2.5rem;
--spacing-lg: 3rem;
--spacing-xl: 3.5rem;
--spacing-2xl: 4rem;
--spacing-3xl: 4.5rem;
--spacing-4xl: 5rem;
--spacing-5xl: 5.5rem;
--spacing-6xl: 6rem;
--spacing-7xl: 6.5rem;
--spacing-8xl: 7rem;
/* ==================== */
/* Radius */
/* ==================== */
--radius-4xs: 0.25rem; /* 4px */
--radius-3xs: 0.5rem; /* 8px */
--radius-2xs: 0.75rem; /* 12px */
--radius-xs: 1rem; /* 16px */
--radius-sm: 1.5rem; /* 24px */
--radius-md: 2rem; /* 32px */
--radius-lg: 2.5rem; /* 40px */
--radius-xl: 3rem; /* 48px */
--radius-2xl: 3.5rem; /* 56px */
--radius-3xl: 4rem; /* 64px */
--radius-round: 999px; /* 完全圆角 */
/* ==================== */
/* Typography */
/* ==================== */
--font-family-heading: Inter;
--font-family-body: Inter;
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-bold: 700;
--font-size-body-xs: 0.75rem;
--font-size-body-sm: 0.875rem;
--font-size-body-md: 1rem;
--font-size-body-lg: 1.125rem;
--font-size-heading-xs: 1.25rem;
--font-size-heading-sm: 1.5rem;
--font-size-heading-md: 2rem;
--font-size-heading-lg: 2.5rem;
--font-size-heading-xl: 3rem;
--font-size-heading-2xl: 3.75rem;
--line-height-body-xs: 1.25rem;
--line-height-body-sm: 1.5rem;
--line-height-body-md: 1.5rem;
--line-height-body-lg: 1.75rem;
--line-height-heading-xs: 2rem;
--line-height-heading-sm: 2.5rem;
--line-height-heading-md: 3rem;
--line-height-heading-lg: 3.75rem;
--line-height-heading-xl: 5rem;
--paragraph-spacing-body-xs: 0.75rem;
--paragraph-spacing-body-sm: 0.875rem;
--paragraph-spacing-body-md: 1rem;
--paragraph-spacing-body-lg: 1.125rem;
--paragraph-spacing-heading-xs: 1.25rem;
--paragraph-spacing-heading-sm: 1.5rem;
--paragraph-spacing-heading-md: 2rem;
--paragraph-spacing-heading-lg: 2.5rem;
--paragraph-spacing-heading-xl: 3rem;
--paragraph-spacing-heading-2xl: 3.75rem;
}
/* ==================== */
/* Dark Mode */
/* ==================== */
@layer theme {
.dark {
--color-background: hsla(240, 6%, 10%, 1);
--color-background-subtle: hsla(0, 0%, 100%, 0.02);
--color-foreground: hsla(0, 0%, 100%, 0.9);
--color-foreground-secondary: hsla(0, 0%, 100%, 0.6);
--color-foreground-muted: hsla(0, 0%, 100%, 0.4);
--color-card: hsla(0, 0%, 0%, 1);
--color-popover: hsla(0, 0%, 0%, 1);
--color-border: hsla(0, 0%, 100%, 0.1);
--color-border-hover: hsla(0, 0%, 100%, 0.2);
--color-border-active: hsla(0, 0%, 100%, 0.3);
--color-ring: hsla(84, 81%, 44%, 0.4);
--color-secondary: hsla(0, 0%, 100%, 0.1);
--color-secondary-hover: hsla(0, 0%, 100%, 0.2);
--color-secondary-active: hsla(0, 0%, 100%, 0.25);
--color-muted: hsla(0, 0%, 100%, 0.1);
--color-accent: hsla(0, 0%, 100%, 0.1);
--color-ghost-hover: hsla(0, 0%, 100%, 0.1);
--color-ghost-active: hsla(0, 0%, 100%, 0.15);
--color-sidebar: hsla(0, 0%, 0%, 1);
--color-sidebar-accent: hsla(0, 0%, 100%, 0.1);
--color-error-base: hsla(0, 91%, 71%, 1);
--color-error-text: hsla(0, 93%, 94%, 1);
--color-error-bg: hsla(0, 63%, 31%, 1);
--color-error-text-hover: hsla(0, 96%, 89%, 1);
--color-error-bg-hover: hsla(0, 70%, 35%, 1);
--color-error-border: hsla(0, 74%, 42%, 1);
--color-error-border-hover: hsla(0, 72%, 51%, 1);
--color-error-active: hsla(0, 94%, 82%, 1);
--color-success-base: hsla(142, 69%, 58%, 1);
--color-success-text-hover: hsla(141, 79%, 85%, 1);
--color-success-bg: hsla(144, 61%, 20%, 1);
--color-success-bg-hover: hsla(143, 64%, 24%, 1);
--color-warning-base: hsla(43, 96%, 56%, 1);
--color-warning-text-hover: hsla(48, 97%, 77%, 1);
--color-warning-bg: hsla(22, 78%, 26%, 1);
--color-warning-bg-hover: hsla(23, 83%, 31%, 1);
--color-warning-active: hsla(32, 95%, 44%, 1);
}
}
/* ==================== */
/* Base Styles */
/* ==================== */
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

View File

@@ -0,0 +1,870 @@
:root {
/* Typography: Desktop mode */
--Font_family--Heading: Inter;
--Font_weight--Regular: 400px;
--Font_size--Heading--2xl: 60px;
--Font_size--Heading--xl: 48px;
--Font_size--Heading--lg: 40px;
--Font_size--Heading--md: 32px;
--Font_size--Heading--sm: 24px;
--Font_size--Heading--xs: 20px;
--Line_height--Heading--xl: 80px;
--Line_height--Body--lg: 28px;
--Line_height--Body--md: 24px;
--Line_height--Body--sm: 24px;
--Line_height--Body--xs: 20px;
--Paragraph_spacing--Body--lg: 18px;
--Paragraph_spacing--Body--md: 16px;
--Paragraph_spacing--Body--sm: 14px;
--Paragraph_spacing--Body--xs: 12px;
--Line_height--Heading--lg: 60px;
--Line_height--Heading--md: 48px;
--Line_height--Heading--sm: 40px;
--Line_height--Heading--xs: 32px;
--Font_size--Body--lg: 18px;
--Font_size--Body--md: 16px;
--Font_size--Body--sm: 14px;
--Font_size--Body--xs: 12px;
--Font_weight--Italic: 400px;
--Font_weight--Medium: 500px;
--Font_weight--Bold: 700px;
--Font_family--Body: Inter;
--Paragraph_spacing--Heading--2xl: 60px;
--Paragraph_spacing--Heading--xl: 48px;
--Paragraph_spacing--Heading--lg: 40px;
--Paragraph_spacing--Heading--md: 32px;
--Paragraph_spacing--Heading--sm: 24px;
--Paragraph_spacing--Heading--xs: 20px;
--typography_components--h1--font-family: Inter;
--typography_components--h2--font-family: Inter;
--typography_components--h2--font-size: 30px;
--typography_components--h2--line-height: 36px;
--typography_components--h2--font-weight: 600;
--typography_components--h2--letter-spacing: -0.4000000059604645px;
--typography_components--h1--font-size: 36px;
--typography_components--h1--font-size-lg: 48px;
--typography_components--h1--line-height: 40px;
--typography_components--h1--font-weight: 800;
--typography_components--h1--letter-spacing: -0.4000000059604645px;
--typography_components--h3--font-family: Inter;
--typography_components--h3--font-size: 24px;
--typography_components--h3--line-height: 32px;
--typography_components--h3--font-weight: 600;
--typography_components--h3--letter-spacing: -0.4000000059604645px;
--typography_components--h4--font-family: Inter;
--typography_components--h4--font-size: 20px;
--typography_components--h4--line-height: 28px;
--typography_components--h4--font-weight: 600;
--typography_components--h4--letter-spacing: -0.4000000059604645px;
--typography_components--p--font-family: Inter;
--typography_components--p--font-size: 16px;
--typography_components--p--line-height: 28px;
--typography_components--p--font-weight: 400;
--typography_components--p--letter-spacing: 0px;
--typography_components--blockquote--font-family: Inter;
--typography_components--blockquote--font-size: 16px;
--typography_components--blockquote--line-height: 24px;
--typography_components--blockquote--letter-spacing: 0px;
--typography_components--blockquote--font-style: italic;
--typography_components--list--font-family: Inter;
--typography_components--list--font-size: 16px;
--typography_components--list--line-height: 28px;
--typography_components--list--letter-spacing: 0px;
--typography_components--inline_code--font-family: Menlo;
--typography_components--inline_code--font-size: 14px;
--typography_components--inline_code--line-height: 20px;
--typography_components--inline_code--font-weight: 600;
--typography_components--inline_code--letter-spacing: 0px;
--typography_components--lead--font-family: Inter;
--typography_components--lead--font-size: 20px;
--typography_components--lead--line-height: 28px;
--typography_components--lead--font-weight: 400;
--typography_components--lead--letter-spacing: 0px;
--typography_components--large--font-family: Inter;
--typography_components--large--font-size: 18px;
--typography_components--large--line-height: 28px;
--typography_components--large--font-weight: 600;
--typography_components--large--letter-spacing: 0px;
--typography_components--small--font-family: Inter;
--typography_components--small--font-size: 14px;
--typography_components--small--line-height: 14px;
--typography_components--small--font-weight: 500;
--typography_components--table--font-family: Inter;
--typography_components--table--font-size: 16px;
--typography_components--table--font-weight: 400;
--typography_components--table--font-weight-bold: 700;
--typography_components--table--letter-spacing: 0px;
/* Spacing and sizing: Desktop */
--Border_width--sm: 1px;
--Border_width--md: 2px;
--Border_width--lg: 3px;
--Radius--4xs: 4px;
--Radius--3xs: 8px;
--Radius--2xs: 12px;
--Radius--xs: 16px;
--Radius--sm: 24px;
--Radius--md: 32px;
--Radius--lg: 40px;
--Radius--xl: 48px;
--Radius--2xl: 56px;
--Radius--3xl: 64px;
--Radius--round: 999px;
--Spacing--5xs: 4px;
--Spacing--4xs: 8px;
--Spacing--3xs: 12px;
--Spacing--2xs: 16px;
--Spacing--xs: 24px;
--Spacing--sm: 32px;
--Spacing--md: 40px;
--Spacing--lg: 48px;
--Spacing--xl: 56px;
--Spacing--2xl: 64px;
--Spacing--3xl: 72px;
--Spacing--4xl: 80px;
--Spacing--5xl: 88px;
--Spacing--6xl: 96px;
--Spacing--7xl: 104px;
--Spacing--8xl: 112px;
--Sizing--5xs: 4px;
--Sizing--4xs: 8px;
--Sizing--3xs: 12px;
--Sizing--2xs: 16px;
--Sizing--xs: 24px;
--Sizing--sm: 32px;
--Sizing--md: 40px;
--Sizing--lg: 48px;
--Sizing--xl: 56px;
--Sizing--2xl: 64px;
--Sizing--3xl: 72px;
--Sizing--4xl: 80px;
--Sizing--5xl: 88px;
/* Color: Light mode */
--Opacity--Red--Red-100: var(--Primitive--Red--600);
--Opacity--Red--Red-80: hsla(0, 72%, 51%, 0.8);
--Opacity--Red--Red-60: hsla(0, 72%, 51%, 0.6);
--Opacity--Red--Red-40: hsla(0, 72%, 51%, 0.4);
--Opacity--Red--Red-20: hsla(0, 72%, 51%, 0.2);
--Opacity--Red--Red-10: hsla(0, 72%, 51%, 0.1);
--Opacity--Green--Green-100: var(--Primitive--Green--600);
--Opacity--Green--Green-80: hsla(142, 76%, 36%, 0.8);
--Opacity--Green--Green-60: hsla(142, 76%, 36%, 0.6);
--Opacity--Green--Green-40: hsla(142, 76%, 36%, 0.4);
--Opacity--Green--Green-20: hsla(142, 76%, 36%, 0.2);
--Opacity--Green--Green-10: hsla(142, 76%, 36%, 0.1);
--Opacity--Yellow--Yellow-100: var(--Primitive--Amber--400);
--Opacity--Yellow--Yellow-80: hsla(48, 96%, 53%, 0.8);
--Opacity--Yellow--Yellow-60: hsla(48, 96%, 53%, 0.6);
--Opacity--Yellow--Yellow-40: hsla(48, 96%, 53%, 0.4);
--Opacity--Yellow--Yellow-20: hsla(48, 96%, 53%, 0.2);
--Opacity--Yellow--Yellow-10: hsla(48, 96%, 53%, 0.1);
--Opacity--Violet--Violet-100: var(--Primitive--Violet--500);
--Opacity--Violet--Violet-80: hsla(258, 90%, 66%, 0.8);
--Opacity--Violet--Violet-60: hsla(258, 90%, 66%, 0.6);
--Opacity--Violet--Violet-40: hsla(258, 90%, 66%, 0.4);
--Opacity--Violet--Violet-20: hsla(258, 90%, 66%, 0.2);
--Opacity--Violet--Violet-10: hsla(258, 90%, 66%, 0.1);
--Opacity--Indigo--Indigo-100: var(--Primitive--Indigo--500);
--Opacity--Indigo--Indigo-80: hsla(239, 84%, 67%, 0.8);
--Opacity--Indigo--Indigo-60: hsla(239, 84%, 67%, 0.6);
--Opacity--Indigo--Indigo-40: hsla(239, 84%, 67%, 0.4);
--Opacity--Indigo--Indigo-20: hsla(239, 84%, 67%, 0.2);
--Opacity--Indigo--Indigo-10: hsla(239, 84%, 67%, 0.1);
--Opacity--Blue--Blue-100: var(--Primitive--Blue--500);
--Opacity--Blue--Blue-80: hsla(217, 91%, 60%, 0.8);
--Opacity--Blue--Blue-60: hsla(217, 91%, 60%, 0.6);
--Opacity--Blue--Blue-40: hsla(217, 91%, 60%, 0.4);
--Opacity--Blue--Blue-20: hsla(217, 91%, 60%, 0.2);
--Opacity--Blue--Blue-10: hsla(217, 91%, 60%, 0.1);
--Opacity--Grey--Grey-100: var(--Primitive--Gray--500);
--Opacity--Grey--Grey-80: hsla(220, 9%, 46%, 0.8);
--Opacity--Grey--Grey-60: hsla(220, 9%, 46%, 0.6);
--Opacity--Grey--Grey-40: hsla(220, 9%, 46%, 0.4);
--Opacity--Grey--Grey-20: hsla(220, 9%, 46%, 0.2);
--Opacity--Grey--Grey-10: hsla(220, 9%, 46%, 0.1);
--Opacity--White--White-100: var(--Primitive--White);
--Opacity--White--White-80: hsla(0, 0%, 100%, 0.8);
--Opacity--White--White-60: hsla(0, 0%, 100%, 0.6);
--Opacity--White--White-40: hsla(0, 0%, 100%, 0.4);
--Opacity--White--White-20: hsla(0, 0%, 100%, 0.2);
--Opacity--White--White-10: hsla(0, 0%, 100%, 0.1);
--Opacity--White--White-0: hsla(0, 0%, 100%, 0);
--Status--Error--colorErrorBg: var(--color--Red--50);
--Status--Error--colorErrorBgHover: var(--color--Red--100);
--Status--Error--colorErrorBorder: var(--color--Red--200);
--Status--Error--colorErrorBorderHover: var(--color--Red--300);
--Status--Error--colorErrorBase: var(--color--Red--500);
--Status--Error--colorErrorActive: var(--color--Red--600);
--Status--Error--colorErrorTextHover: var(--color--Red--700);
--Status--Error--colorErrorText: var(--color--Red--800);
--Status--Success--colorSuccessBg: var(--color--Green--50);
--Status--Success--colorSuccessBgHover: var(--color--Green--100);
--Status--Success--colorSuccessBase: var(--color--Green--500);
--Status--Success--colorSuccessTextHover: var(--color--Green--700);
--Status--Warning--colorWarningBg: var(--color--Yellow--50);
--Status--Warning--colorWarningBgHover: var(--color--Yellow--100);
--Status--Warning--colorWarningBase: var(--color--Yellow--500);
--Status--Warning--colorWarningActive: var(--color--Yellow--600);
--Status--Warning--colorWarningTextHover: var(--color--Yellow--700);
--Primitive--Black: hsla(0, 0%, 0%, 1);
--Primitive--White: hsla(0, 0%, 100%, 1);
--Brand--Base_Colors--Primary: var(--Primitive--Lime--500);
--Primitive--Neutral--50: hsla(0, 0%, 98%, 1);
--Primitive--Neutral--100: hsla(0, 0%, 96%, 1);
--Primitive--Neutral--200: hsla(0, 0%, 90%, 1);
--Primitive--Neutral--300: hsla(0, 0%, 83%, 1);
--Primitive--Neutral--400: hsla(0, 0%, 64%, 1);
--Primitive--Neutral--500: hsla(0, 0%, 45%, 1);
--Primitive--Neutral--600: hsla(215, 14%, 34%, 1);
--Primitive--Neutral--700: hsla(0, 0%, 25%, 1);
--Primitive--Neutral--800: hsla(0, 0%, 15%, 1);
--Primitive--Neutral--900: hsla(0, 0%, 9%, 1);
--Primitive--Neutral--950: hsla(0, 0%, 4%, 1);
--Primitive--Stone--50: hsla(60, 9%, 98%, 1);
--Primitive--Stone--100: hsla(60, 5%, 96%, 1);
--Primitive--Stone--200: hsla(20, 6%, 90%, 1);
--Primitive--Stone--300: hsla(24, 6%, 83%, 1);
--Primitive--Stone--400: hsla(24, 5%, 64%, 1);
--Primitive--Stone--500: hsla(25, 5%, 45%, 1);
--Primitive--Stone--600: hsla(33, 5%, 32%, 1);
--Primitive--Stone--700: hsla(30, 6%, 25%, 1);
--Primitive--Stone--800: hsla(12, 6%, 15%, 1);
--Primitive--Stone--900: hsla(24, 10%, 10%, 1);
--Primitive--Stone--950: hsla(20, 14%, 4%, 1);
--Primitive--Zinc--50: hsla(0, 0%, 98%, 1);
--Primitive--Zinc--100: hsla(240, 5%, 96%, 1);
--Primitive--Zinc--200: hsla(240, 6%, 90%, 1);
--Primitive--Zinc--300: hsla(240, 5%, 84%, 1);
--Primitive--Zinc--400: hsla(240, 5%, 65%, 1);
--Primitive--Zinc--500: hsla(240, 4%, 46%, 1);
--Primitive--Zinc--600: hsla(240, 5%, 34%, 1);
--Primitive--Zinc--700: hsla(240, 5%, 26%, 1);
--Primitive--Zinc--800: hsla(240, 4%, 16%, 1);
--Primitive--Zinc--900: hsla(240, 6%, 10%, 1);
--Primitive--Zinc--950: hsla(240, 10%, 4%, 1);
--Primitive--Slate--50: hsla(210, 40%, 98%, 1);
--Primitive--Slate--100: hsla(210, 40%, 96%, 1);
--Primitive--Slate--200: hsla(214, 32%, 91%, 1);
--Primitive--Slate--300: hsla(213, 27%, 84%, 1);
--Primitive--Slate--400: hsla(215, 20%, 65%, 1);
--Primitive--Slate--500: hsla(215, 16%, 47%, 1);
--Primitive--Slate--600: hsla(215, 19%, 35%, 1);
--Primitive--Slate--700: hsla(215, 25%, 27%, 1);
--Primitive--Slate--800: hsla(217, 33%, 17%, 1);
--Primitive--Slate--900: hsla(222, 47%, 11%, 1);
--Primitive--Slate--950: hsla(229, 84%, 5%, 1);
--Primitive--Gray--50: hsla(210, 20%, 98%, 1);
--Primitive--Gray--100: hsla(220, 14%, 96%, 1);
--Primitive--Gray--200: hsla(220, 13%, 91%, 1);
--Primitive--Gray--300: hsla(216, 12%, 84%, 1);
--Primitive--Gray--400: hsla(218, 11%, 65%, 1);
--Primitive--Gray--500: hsla(220, 9%, 46%, 1);
--Primitive--Gray--600: hsla(0, 0%, 32%, 1);
--Primitive--Gray--700: hsla(217, 19%, 27%, 1);
--Primitive--Gray--800: hsla(215, 28%, 17%, 1);
--Primitive--Gray--900: hsla(221, 39%, 11%, 1);
--Primitive--Gray--950: hsla(224, 71%, 4%, 1);
--Primitive--Red--50: hsla(0, 86%, 97%, 1);
--Primitive--Red--100: hsla(0, 93%, 94%, 1);
--Primitive--Red--200: hsla(0, 96%, 89%, 1);
--Primitive--Red--300: hsla(0, 94%, 82%, 1);
--Primitive--Red--400: hsla(0, 91%, 71%, 1);
--Primitive--Red--500: hsla(0, 84%, 60%, 1);
--Primitive--Red--600: hsla(0, 72%, 51%, 1);
--Primitive--Red--700: hsla(0, 74%, 42%, 1);
--Primitive--Red--800: hsla(0, 70%, 35%, 1);
--Primitive--Red--900: hsla(0, 63%, 31%, 1);
--Primitive--Red--950: hsla(0, 75%, 15%, 1);
--Primitive--Orange--50: hsla(33, 100%, 96%, 1);
--Primitive--Orange--100: hsla(34, 100%, 92%, 1);
--Primitive--Orange--200: hsla(32, 98%, 83%, 1);
--Primitive--Orange--300: hsla(31, 97%, 72%, 1);
--Primitive--Orange--400: hsla(27, 96%, 61%, 1);
--Primitive--Orange--500: hsla(25, 95%, 53%, 1);
--Primitive--Orange--600: hsla(21, 90%, 48%, 1);
--Primitive--Orange--700: hsla(17, 88%, 40%, 1);
--Primitive--Orange--800: hsla(15, 79%, 34%, 1);
--Primitive--Orange--900: hsla(15, 75%, 28%, 1);
--Primitive--Orange--950: hsla(13, 81%, 15%, 1);
--Primitive--Amber--50: hsla(48, 100%, 96%, 1);
--Primitive--Amber--100: hsla(48, 96%, 89%, 1);
--Primitive--Amber--200: hsla(48, 97%, 77%, 1);
--Primitive--Amber--300: hsla(46, 97%, 65%, 1);
--Primitive--Amber--400: hsla(43, 96%, 56%, 1);
--Primitive--Amber--500: hsla(38, 92%, 50%, 1);
--Primitive--Amber--600: hsla(32, 95%, 44%, 1);
--Primitive--Amber--700: hsla(26, 90%, 37%, 1);
--Primitive--Amber--800: hsla(23, 83%, 31%, 1);
--Primitive--Amber--900: hsla(22, 78%, 26%, 1);
--Primitive--Amber--950: hsla(21, 92%, 14%, 1);
--Primitive--Yellow--50: hsla(55, 92%, 95%, 1);
--Primitive--Yellow--100: hsla(55, 97%, 88%, 1);
--Primitive--Yellow--200: hsla(53, 98%, 77%, 1);
--Primitive--Yellow--300: hsla(50, 98%, 64%, 1);
--Primitive--Yellow--400: hsla(48, 96%, 53%, 1);
--Primitive--Yellow--500: hsla(45, 93%, 47%, 1);
--Primitive--Yellow--600: hsla(41, 96%, 40%, 1);
--Primitive--Yellow--700: hsla(35, 92%, 33%, 1);
--Primitive--Yellow--800: hsla(32, 81%, 29%, 1);
--Primitive--Yellow--900: hsla(28, 73%, 26%, 1);
--Primitive--Yellow--950: hsla(26, 83%, 14%, 1);
--Primitive--Lime--50: hsla(78, 92%, 95%, 1);
--Primitive--Lime--100: hsla(80, 89%, 89%, 1);
--Primitive--Lime--200: hsla(81, 88%, 80%, 1);
--Primitive--Lime--300: hsla(82, 85%, 67%, 1);
--Primitive--Lime--400: hsla(83, 78%, 55%, 1);
--Primitive--Lime--500: hsla(84, 81%, 44%, 1);
--Primitive--Lime--600: hsla(85, 85%, 35%, 1);
--Primitive--Lime--700: hsla(86, 78%, 27%, 1);
--Primitive--Lime--800: hsla(86, 69%, 23%, 1);
--Primitive--Lime--900: hsla(88, 61%, 20%, 1);
--Primitive--Lime--950: hsla(89, 80%, 10%, 1);
--Primitive--Green--50: hsla(138, 76%, 97%, 1);
--Primitive--Green--100: hsla(141, 84%, 93%, 1);
--Primitive--Green--200: hsla(141, 79%, 85%, 1);
--Primitive--Green--300: hsla(142, 77%, 73%, 1);
--Primitive--Green--400: hsla(142, 69%, 58%, 1);
--Primitive--Green--500: hsla(142, 71%, 45%, 1);
--Primitive--Green--600: hsla(142, 76%, 36%, 1);
--Primitive--Green--700: hsla(142, 72%, 29%, 1);
--Primitive--Green--800: hsla(143, 64%, 24%, 1);
--Primitive--Green--900: hsla(144, 61%, 20%, 1);
--Primitive--Green--950: hsla(145, 80%, 10%, 1);
--Primitive--Emerald--50: hsla(152, 81%, 96%, 1);
--Primitive--Emerald--100: hsla(149, 80%, 90%, 1);
--Primitive--Emerald--200: hsla(152, 76%, 80%, 1);
--Primitive--Emerald--300: hsla(156, 72%, 67%, 1);
--Primitive--Emerald--400: hsla(158, 64%, 52%, 1);
--Primitive--Emerald--500: hsla(160, 84%, 39%, 1);
--Primitive--Emerald--600: hsla(161, 94%, 30%, 1);
--Primitive--Emerald--700: hsla(163, 94%, 24%, 1);
--Primitive--Emerald--800: hsla(163, 88%, 20%, 1);
--Primitive--Emerald--900: hsla(164, 86%, 16%, 1);
--Primitive--Emerald--950: hsla(166, 91%, 9%, 1);
--Primitive--Teal--50: hsla(166, 76%, 97%, 1);
--Primitive--Teal--100: hsla(167, 85%, 89%, 1);
--Primitive--Teal--200: hsla(168, 84%, 78%, 1);
--Primitive--Teal--300: hsla(171, 77%, 64%, 1);
--Primitive--Teal--400: hsla(172, 66%, 50%, 1);
--Primitive--Teal--500: hsla(173, 80%, 40%, 1);
--Primitive--Teal--600: hsla(175, 84%, 32%, 1);
--Primitive--Teal--700: hsla(175, 77%, 26%, 1);
--Primitive--Teal--800: hsla(176, 69%, 22%, 1);
--Primitive--Teal--900: hsla(176, 61%, 19%, 1);
--Primitive--Teal--950: hsla(179, 84%, 10%, 1);
--Primitive--Cyan--50: hsla(183, 100%, 96%, 1);
--Primitive--Cyan--100: hsla(185, 96%, 90%, 1);
--Primitive--Cyan--200: hsla(186, 94%, 82%, 1);
--Primitive--Cyan--300: hsla(187, 92%, 69%, 1);
--Primitive--Cyan--400: hsla(188, 86%, 53%, 1);
--Primitive--Cyan--500: hsla(189, 94%, 43%, 1);
--Primitive--Cyan--600: hsla(192, 91%, 36%, 1);
--Primitive--Cyan--700: hsla(193, 82%, 31%, 1);
--Primitive--Cyan--800: hsla(194, 70%, 27%, 1);
--Primitive--Cyan--900: hsla(196, 64%, 24%, 1);
--Primitive--Cyan--950: hsla(197, 79%, 15%, 1);
--Primitive--Sky--50: hsla(204, 100%, 97%, 1);
--Primitive--Sky--100: hsla(204, 94%, 94%, 1);
--Primitive--Sky--200: hsla(201, 94%, 86%, 1);
--Primitive--Sky--300: hsla(199, 95%, 74%, 1);
--Primitive--Sky--400: hsla(198, 93%, 60%, 1);
--Primitive--Sky--500: hsla(199, 89%, 48%, 1);
--Primitive--Sky--600: hsla(200, 98%, 39%, 1);
--Primitive--Sky--700: hsla(201, 96%, 32%, 1);
--Primitive--Sky--800: hsla(201, 90%, 27%, 1);
--Primitive--Sky--900: hsla(202, 80%, 24%, 1);
--Primitive--Sky--950: hsla(204, 80%, 16%, 1);
--Primitive--Blue--50: hsla(214, 100%, 97%, 1);
--Primitive--Blue--100: hsla(214, 95%, 93%, 1);
--Primitive--Blue--200: hsla(213, 97%, 87%, 1);
--Primitive--Blue--300: hsla(212, 96%, 78%, 1);
--Primitive--Blue--400: hsla(213, 94%, 68%, 1);
--Primitive--Blue--500: hsla(217, 91%, 60%, 1);
--Primitive--Blue--600: hsla(221, 83%, 53%, 1);
--Primitive--Blue--700: hsla(224, 76%, 48%, 1);
--Primitive--Blue--800: hsla(226, 71%, 40%, 1);
--Primitive--Blue--900: hsla(224, 64%, 33%, 1);
--Primitive--Blue--950: hsla(226, 57%, 21%, 1);
--Primitive--Indigo--50: hsla(226, 100%, 97%, 1);
--Primitive--Indigo--100: hsla(226, 100%, 94%, 1);
--Primitive--Indigo--200: hsla(228, 96%, 89%, 1);
--Primitive--Indigo--300: hsla(230, 94%, 82%, 1);
--Primitive--Indigo--400: hsla(234, 89%, 74%, 1);
--Primitive--Indigo--500: hsla(239, 84%, 67%, 1);
--Primitive--Indigo--600: hsla(243, 75%, 59%, 1);
--Primitive--Indigo--700: hsla(245, 58%, 51%, 1);
--Primitive--Indigo--800: hsla(244, 55%, 41%, 1);
--Primitive--Indigo--900: hsla(242, 47%, 34%, 1);
--Primitive--Indigo--950: hsla(244, 47%, 20%, 1);
--Primitive--Violet--50: hsla(250, 100%, 98%, 1);
--Primitive--Violet--100: hsla(251, 91%, 95%, 1);
--Primitive--Violet--200: hsla(251, 95%, 92%, 1);
--Primitive--Violet--300: hsla(253, 95%, 85%, 1);
--Primitive--Violet--400: hsla(255, 92%, 76%, 1);
--Primitive--Violet--500: hsla(258, 90%, 66%, 1);
--Primitive--Violet--600: hsla(262, 83%, 58%, 1);
--Primitive--Violet--700: hsla(263, 70%, 50%, 1);
--Primitive--Violet--800: hsla(263, 69%, 42%, 1);
--Primitive--Violet--900: hsla(264, 67%, 35%, 1);
--Primitive--Violet--950: hsla(262, 78%, 23%, 1);
--Primitive--Purple--50: hsla(270, 100%, 98%, 1);
--Primitive--Purple--100: hsla(269, 100%, 95%, 1);
--Primitive--Purple--200: hsla(269, 100%, 92%, 1);
--Primitive--Purple--300: hsla(269, 97%, 85%, 1);
--Primitive--Purple--400: hsla(270, 95%, 75%, 1);
--Primitive--Purple--500: hsla(271, 91%, 65%, 1);
--Primitive--Purple--600: hsla(271, 81%, 56%, 1);
--Primitive--Purple--700: hsla(272, 72%, 47%, 1);
--Primitive--Purple--800: hsla(273, 67%, 39%, 1);
--Primitive--Purple--900: hsla(274, 66%, 32%, 1);
--Primitive--Purple--950: hsla(274, 87%, 21%, 1);
--Primitive--Fuchsia--50: hsla(289, 100%, 98%, 1);
--Primitive--Fuchsia--100: hsla(287, 100%, 95%, 1);
--Primitive--Fuchsia--200: hsla(288, 96%, 91%, 1);
--Primitive--Fuchsia--300: hsla(291, 93%, 83%, 1);
--Primitive--Fuchsia--400: hsla(292, 91%, 73%, 1);
--Primitive--Fuchsia--500: hsla(292, 84%, 61%, 1);
--Primitive--Fuchsia--600: hsla(293, 69%, 49%, 1);
--Primitive--Fuchsia--700: hsla(295, 72%, 40%, 1);
--Primitive--Fuchsia--800: hsla(295, 70%, 33%, 1);
--Primitive--Fuchsia--900: hsla(297, 64%, 28%, 1);
--Primitive--Fuchsia--950: hsla(297, 90%, 16%, 1);
--Primitive--Pink--50: hsla(327, 73%, 97%, 1);
--Primitive--Pink--100: hsla(326, 78%, 95%, 1);
--Primitive--Pink--200: hsla(326, 85%, 90%, 1);
--Primitive--Pink--300: hsla(327, 87%, 82%, 1);
--Primitive--Pink--400: hsla(329, 86%, 70%, 1);
--Primitive--Pink--500: hsla(330, 81%, 60%, 1);
--Primitive--Pink--600: hsla(333, 71%, 51%, 1);
--Primitive--Pink--700: hsla(335, 78%, 42%, 1);
--Primitive--Pink--800: hsla(336, 74%, 35%, 1);
--Primitive--Pink--900: hsla(336, 69%, 30%, 1);
--Primitive--Pink--950: hsla(336, 84%, 17%, 1);
--Primitive--Rose--50: hsla(356, 100%, 97%, 1);
--Primitive--Rose--100: hsla(356, 100%, 95%, 1);
--Primitive--Rose--200: hsla(353, 96%, 90%, 1);
--Primitive--Rose--300: hsla(353, 96%, 82%, 1);
--Primitive--Rose--400: hsla(351, 95%, 71%, 1);
--Primitive--Rose--500: hsla(350, 89%, 60%, 1);
--Primitive--Rose--600: hsla(347, 77%, 50%, 1);
--Primitive--Rose--700: hsla(345, 83%, 41%, 1);
--Primitive--Rose--800: hsla(343, 80%, 35%, 1);
--Primitive--Rose--900: hsla(342, 75%, 30%, 1);
--Primitive--Rose--950: hsla(343, 88%, 16%, 1);
--Brand--Base_Colors--Destructive: var(--Primitive--Red--500);
--Brand--Base_Colors--Success: var(--Primitive--Green--500);
--Brand--Base_Colors--Warning: var(--Primitive--Amber--500);
--Brand--Base_Colors--White: var(--Primitive--White);
--Brand--Base_Colors--Black: var(--Primitive--Black);
--Brand--Semantic_Colors--Background: var(--Primitive--Zinc--50); /*页面背景色:应用在整个页面的最底层。*/
--Brand--Semantic_Colors--Background-subtle: hsla(
0,
0%,
0%,
0.02
); /*细微背景色:用于需要与主背景有微弱区分的区域,如代码块背景。*/
--Brand--Semantic_Colors--Foreground: hsla(0, 0%, 0%, 0.9); /*主要前景/文字色:用于正文、标题等。*/
--Brand--Semantic_Colors--Foreground-secondary: hsla(0, 0%, 0%, 0.6); /*次要前景/文字色:用于辅助性文本、描述。*/
--Brand--Semantic_Colors--Foreground-muted: hsla(0, 0%, 0%, 0.4); /*静默前景/文字色:用于禁用状态的文字、占位符。*/
--Brand--Semantic_Colors--Border: hsla(0, 0%, 0%, 0.1); /*默认边框色:用于卡片、输入框、分隔线。*/
--Brand--Semantic_Colors--Border-hover: hsla(0, 0%, 0%, 0.2); /*激活边框色:用于元素被按下或激活时的边框。*/
--Brand--Semantic_Colors--Border-active: hsla(0, 0%, 0%, 0.3); /*激活边框色:用于元素被按下或激活时的边框。*/
--Brand--Semantic_Colors--Ring: hsla(
84,
81%,
44%,
0.4
); /*聚焦环颜色:用于输入框等元素在聚焦 (Focus) 状态下的外发光。*/
--Brand--UI_Element_Colors--Modal--Backdrop: hsla(0, 0%, 0%, 0.4);
--Brand--UI_Element_Colors--Modal--Thumb: hsla(0, 0%, 0%, 0.2);
--Brand--UI_Element_Colors--Modal--Thumb_Hover: hsla(0, 0%, 0%, 0.3);
--Brand--UI_Element_Colors--Icon--Default: var(--Brand--Semantic_Colors--Foreground-secondary);
--Brand--UI_Element_Colors--Icon--Hover: var(--Brand--Semantic_Colors--Foreground);
--Brand--UI_Element_Colors--Input_Select--Background: var(--Brand--Base_Colors--White);
--Brand--UI_Element_Colors--Input_Select--Border: var(--Brand--Semantic_Colors--Border);
--Brand--UI_Element_Colors--Input_Select--Border_Hover: var(--Brand--Semantic_Colors--Border-hover);
--Brand--UI_Element_Colors--Input_Select--Border_Focus: var(--Brand--Base_Colors--Primary);
--Brand--UI_Element_Colors--Primary_Button--Background: var(--Brand--Base_Colors--Primary);
--Brand--UI_Element_Colors--Card_Container--Background: var(--Brand--Base_Colors--White);
--Brand--UI_Element_Colors--Card_Container--Border: var(--Brand--Semantic_Colors--Border);
--Brand--UI_Element_Colors--Ghost_Button--Background: hsla(0, 0%, 0%, 0);
--Brand--UI_Element_Colors--Ghost_Button--Text: var(--Brand--Semantic_Colors--Foreground);
--Brand--UI_Element_Colors--Ghost_Button--Background_Hover: hsla(0, 0%, 0%, 0.05);
--Brand--UI_Element_Colors--Ghost_Button--Background_Active: hsla(0, 0%, 0%, 0.1);
--Brand--UI_Element_Colors--Secondary_Button--Background: hsla(0, 0%, 0%, 0.05);
--Brand--UI_Element_Colors--Secondary_Button--Text: var(--Brand--Semantic_Colors--Foreground);
--Brand--UI_Element_Colors--Secondary_Button--Background_Hover: hsla(0, 0%, 0%, 0.85);
--Brand--UI_Element_Colors--Secondary_Button--Background_Active: hsla(0, 0%, 0%, 0.7);
--Brand--UI_Element_Colors--Secondary_Button--Border: var(--Brand--Semantic_Colors--Border);
--Brand--UI_Element_Colors--Primary_Button--Text: var(--Brand--Base_Colors--White);
--Brand--UI_Element_Colors--Primary_Button--Background_Hover: hsla(84, 81%, 44%, 0.85);
--Brand--UI_Element_Colors--Primary_Button--2nd_Background: hsla(84, 81%, 44%, 0.1);
--Brand--UI_Element_Colors--Primary_Button--3rd_Background: hsla(84, 81%, 44%, 0.05);
--Brand--UI_Element_Colors--Primary_Button--Background_Active: hsla(84, 81%, 44%, 0.7);
--Boolean: false;
/* Color: Dark mode */
--Opacity--Red--Red-100: var(--Primitive--Red--600);
--Opacity--Red--Red-80: hsla(0, 72%, 51%, 0.8);
--Opacity--Red--Red-60: hsla(0, 72%, 51%, 0.6);
--Opacity--Red--Red-40: hsla(0, 72%, 51%, 0.4);
--Opacity--Red--Red-20: hsla(0, 72%, 51%, 0.2);
--Opacity--Red--Red-10: hsla(0, 72%, 51%, 0.1);
--Opacity--Green--Green-100: var(--Primitive--Green--600);
--Opacity--Green--Green-80: hsla(142, 76%, 36%, 0.8);
--Opacity--Green--Green-60: hsla(142, 76%, 36%, 0.6);
--Opacity--Green--Green-40: hsla(142, 76%, 36%, 0.4);
--Opacity--Green--Green-20: hsla(142, 76%, 36%, 0.2);
--Opacity--Green--Green-10: hsla(142, 76%, 36%, 0.1);
--Opacity--Yellow--Yellow-100: var(--Primitive--Yellow--400);
--Opacity--Yellow--Yellow-80: hsla(48, 96%, 53%, 0.8);
--Opacity--Yellow--Yellow-60: hsla(48, 96%, 53%, 0.6);
--Opacity--Yellow--Yellow-40: hsla(48, 96%, 53%, 0.4);
--Opacity--Yellow--Yellow-20: hsla(48, 96%, 53%, 0.2);
--Opacity--Yellow--Yellow-10: hsla(48, 96%, 53%, 0.1);
--Opacity--Violet--Violet-100: var(--Primitive--Violet--500);
--Opacity--Violet--Violet-80: hsla(258, 90%, 66%, 0.8);
--Opacity--Violet--Violet-60: hsla(258, 90%, 66%, 0.6);
--Opacity--Violet--Violet-40: hsla(258, 90%, 66%, 0.4);
--Opacity--Violet--Violet-20: hsla(258, 90%, 66%, 0.2);
--Opacity--Violet--Violet-10: hsla(258, 90%, 66%, 0.1);
--Opacity--Indigo--Indigo-100: var(--Primitive--Indigo--500);
--Opacity--Indigo--Indigo-80: hsla(239, 84%, 67%, 0.8);
--Opacity--Indigo--Indigo-60: hsla(239, 84%, 67%, 0.6);
--Opacity--Indigo--Indigo-40: hsla(239, 84%, 67%, 0.4);
--Opacity--Indigo--Indigo-20: hsla(239, 84%, 67%, 0.2);
--Opacity--Indigo--Indigo-10: hsla(239, 84%, 67%, 0.1);
--Opacity--Blue--Blue-100: var(--Primitive--Blue--500);
--Opacity--Blue--Blue-80: hsla(217, 91%, 60%, 0.8);
--Opacity--Blue--Blue-60: hsla(217, 91%, 60%, 0.6);
--Opacity--Blue--Blue-40: hsla(217, 91%, 60%, 0.4);
--Opacity--Blue--Blue-20: hsla(217, 91%, 60%, 0.2);
--Opacity--Blue--Blue-10: hsla(217, 91%, 60%, 0.1);
--Opacity--Grey--Grey-100: var(--Primitive--Gray--500);
--Opacity--Grey--Grey-80: hsla(220, 9%, 46%, 0.8);
--Opacity--Grey--Grey-60: hsla(220, 9%, 46%, 0.6);
--Opacity--Grey--Grey-40: hsla(220, 9%, 46%, 0.4);
--Opacity--Grey--Grey-20: hsla(220, 9%, 46%, 0.2);
--Opacity--Grey--Grey-10: hsla(220, 9%, 46%, 0.1);
--Opacity--White--White-100: var(--Primitive--White);
--Opacity--White--White-80: hsla(0, 0%, 100%, 0.8);
--Opacity--White--White-60: hsla(0, 0%, 100%, 0.6);
--Opacity--White--White-40: hsla(0, 0%, 100%, 0.4);
--Opacity--White--White-20: hsla(0, 0%, 100%, 0.2);
--Opacity--White--White-10: hsla(0, 0%, 100%, 0.1);
--Opacity--White--White-0: hsla(0, 0%, 100%, 0);
--Status--Error--colorErrorBg: var(--color--Red--900);
--Status--Error--colorErrorBgHover: var(--color--Red--800);
--Status--Error--colorErrorBorder: var(--color--Red--700);
--Status--Error--colorErrorBorderHover: var(--color--Red--600);
--Status--Error--colorErrorBase: var(--color--Red--400);
--Status--Error--colorErrorActive: var(--color--Red--300);
--Status--Error--colorErrorTextHover: var(--color--Red--200);
--Status--Error--colorErrorText: var(--color--Red--100);
--Status--Success--colorSuccessBg: var(--color--Green--900);
--Status--Success--colorSuccessBgHover: var(--color--Green--800);
--Status--Success--colorSuccessBase: var(--color--Green--400);
--Status--Success--colorSuccessTextHover: var(--color--Green--200);
--Status--Warning--colorWarningBg: var(--color--Yellow--900);
--Status--Warning--colorWarningBgHover: var(--color--Yellow--800);
--Status--Warning--colorWarningBase: var(--color--Yellow--400);
--Status--Warning--colorWarningActive: var(--color--Yellow--300);
--Status--Warning--colorWarningTextHover: var(--color--Yellow--200);
--Primitive--Black: hsla(0, 0%, 0%, 1);
--Primitive--White: hsla(0, 0%, 100%, 1);
--Brand--Base_Colors--Primary: var(--Primitive--Lime--500);
--Primitive--Neutral--50: hsla(0, 0%, 98%, 1);
--Primitive--Neutral--100: hsla(0, 0%, 96%, 1);
--Primitive--Neutral--200: hsla(0, 0%, 90%, 1);
--Primitive--Neutral--300: hsla(0, 0%, 83%, 1);
--Primitive--Neutral--400: hsla(0, 0%, 64%, 1);
--Primitive--Neutral--500: hsla(0, 0%, 45%, 1);
--Primitive--Neutral--600: hsla(215, 14%, 34%, 1);
--Primitive--Neutral--700: hsla(0, 0%, 25%, 1);
--Primitive--Neutral--800: hsla(0, 0%, 15%, 1);
--Primitive--Neutral--900: hsla(0, 0%, 9%, 1);
--Primitive--Neutral--950: hsla(0, 0%, 4%, 1);
--Primitive--Stone--50: hsla(60, 9%, 98%, 1);
--Primitive--Stone--100: hsla(60, 5%, 96%, 1);
--Primitive--Stone--200: hsla(20, 6%, 90%, 1);
--Primitive--Stone--300: hsla(24, 6%, 83%, 1);
--Primitive--Stone--400: hsla(24, 5%, 64%, 1);
--Primitive--Stone--500: hsla(25, 5%, 45%, 1);
--Primitive--Stone--600: hsla(33, 5%, 32%, 1);
--Primitive--Stone--700: hsla(30, 6%, 25%, 1);
--Primitive--Stone--800: hsla(12, 6%, 15%, 1);
--Primitive--Stone--900: hsla(24, 10%, 10%, 1);
--Primitive--Stone--950: hsla(20, 14%, 4%, 1);
--Primitive--Zinc--50: hsla(0, 0%, 98%, 1);
--Primitive--Zinc--100: hsla(240, 5%, 96%, 1);
--Primitive--Zinc--200: hsla(240, 6%, 90%, 1);
--Primitive--Zinc--300: hsla(240, 5%, 84%, 1);
--Primitive--Zinc--400: hsla(240, 5%, 65%, 1);
--Primitive--Zinc--500: hsla(240, 4%, 46%, 1);
--Primitive--Zinc--600: hsla(240, 5%, 34%, 1);
--Primitive--Zinc--700: hsla(240, 5%, 26%, 1);
--Primitive--Zinc--800: hsla(240, 4%, 16%, 1);
--Primitive--Zinc--900: hsla(240, 6%, 10%, 1);
--Primitive--Zinc--950: hsla(240, 10%, 4%, 1);
--Primitive--Slate--50: hsla(210, 40%, 98%, 1);
--Primitive--Slate--100: hsla(210, 40%, 96%, 1);
--Primitive--Slate--200: hsla(214, 32%, 91%, 1);
--Primitive--Slate--300: hsla(213, 27%, 84%, 1);
--Primitive--Slate--400: hsla(215, 20%, 65%, 1);
--Primitive--Slate--500: hsla(215, 16%, 47%, 1);
--Primitive--Slate--600: hsla(215, 19%, 35%, 1);
--Primitive--Slate--700: hsla(215, 25%, 27%, 1);
--Primitive--Slate--800: hsla(217, 33%, 17%, 1);
--Primitive--Slate--900: hsla(222, 47%, 11%, 1);
--Primitive--Slate--950: hsla(229, 84%, 5%, 1);
--Primitive--Gray--50: hsla(210, 20%, 98%, 1);
--Primitive--Gray--100: hsla(220, 14%, 96%, 1);
--Primitive--Gray--200: hsla(220, 13%, 91%, 1);
--Primitive--Gray--300: hsla(216, 12%, 84%, 1);
--Primitive--Gray--400: hsla(218, 11%, 65%, 1);
--Primitive--Gray--500: hsla(220, 9%, 46%, 1);
--Primitive--Gray--600: hsla(0, 0%, 32%, 1);
--Primitive--Gray--700: hsla(217, 19%, 27%, 1);
--Primitive--Gray--800: hsla(215, 28%, 17%, 1);
--Primitive--Gray--900: hsla(221, 39%, 11%, 1);
--Primitive--Gray--950: hsla(224, 71%, 4%, 1);
--Primitive--Red--50: hsla(0, 86%, 97%, 1);
--Primitive--Red--100: hsla(0, 93%, 94%, 1);
--Primitive--Red--200: hsla(0, 96%, 89%, 1);
--Primitive--Red--300: hsla(0, 94%, 82%, 1);
--Primitive--Red--400: hsla(0, 91%, 71%, 1);
--Primitive--Red--500: hsla(0, 84%, 60%, 1);
--Primitive--Red--600: hsla(0, 72%, 51%, 1);
--Primitive--Red--700: hsla(0, 74%, 42%, 1);
--Primitive--Red--800: hsla(0, 70%, 35%, 1);
--Primitive--Red--900: hsla(0, 63%, 31%, 1);
--Primitive--Red--950: hsla(0, 75%, 15%, 1);
--Primitive--Orange--50: hsla(33, 100%, 96%, 1);
--Primitive--Orange--100: hsla(34, 100%, 92%, 1);
--Primitive--Orange--200: hsla(32, 98%, 83%, 1);
--Primitive--Orange--300: hsla(31, 97%, 72%, 1);
--Primitive--Orange--400: hsla(27, 96%, 61%, 1);
--Primitive--Orange--500: hsla(25, 95%, 53%, 1);
--Primitive--Orange--600: hsla(21, 90%, 48%, 1);
--Primitive--Orange--700: hsla(17, 88%, 40%, 1);
--Primitive--Orange--800: hsla(15, 79%, 34%, 1);
--Primitive--Orange--900: hsla(15, 75%, 28%, 1);
--Primitive--Orange--950: hsla(13, 81%, 15%, 1);
--Primitive--Amber--50: hsla(48, 100%, 96%, 1);
--Primitive--Amber--100: hsla(48, 96%, 89%, 1);
--Primitive--Amber--200: hsla(48, 97%, 77%, 1);
--Primitive--Amber--300: hsla(46, 97%, 65%, 1);
--Primitive--Amber--400: hsla(43, 96%, 56%, 1);
--Primitive--Amber--500: hsla(38, 92%, 50%, 1);
--Primitive--Amber--600: hsla(32, 95%, 44%, 1);
--Primitive--Amber--700: hsla(26, 90%, 37%, 1);
--Primitive--Amber--800: hsla(23, 83%, 31%, 1);
--Primitive--Amber--900: hsla(22, 78%, 26%, 1);
--Primitive--Amber--950: hsla(21, 92%, 14%, 1);
--Primitive--Yellow--50: hsla(55, 92%, 95%, 1);
--Primitive--Yellow--100: hsla(55, 97%, 88%, 1);
--Primitive--Yellow--200: hsla(53, 98%, 77%, 1);
--Primitive--Yellow--300: hsla(50, 98%, 64%, 1);
--Primitive--Yellow--400: hsla(48, 96%, 53%, 1);
--Primitive--Yellow--500: hsla(45, 93%, 47%, 1);
--Primitive--Yellow--600: hsla(41, 96%, 40%, 1);
--Primitive--Yellow--700: hsla(35, 92%, 33%, 1);
--Primitive--Yellow--800: hsla(32, 81%, 29%, 1);
--Primitive--Yellow--900: hsla(28, 73%, 26%, 1);
--Primitive--Yellow--950: hsla(26, 83%, 14%, 1);
--Primitive--Lime--50: hsla(78, 92%, 95%, 1);
--Primitive--Lime--100: hsla(80, 89%, 89%, 1);
--Primitive--Lime--200: hsla(81, 88%, 80%, 1);
--Primitive--Lime--300: hsla(82, 85%, 67%, 1);
--Primitive--Lime--400: hsla(83, 78%, 55%, 1);
--Primitive--Lime--500: hsla(84, 81%, 44%, 1);
--Primitive--Lime--600: hsla(85, 85%, 35%, 1);
--Primitive--Lime--700: hsla(86, 78%, 27%, 1);
--Primitive--Lime--800: hsla(86, 69%, 23%, 1);
--Primitive--Lime--900: hsla(88, 61%, 20%, 1);
--Primitive--Lime--950: hsla(89, 80%, 10%, 1);
--Primitive--Green--50: hsla(138, 76%, 97%, 1);
--Primitive--Green--100: hsla(141, 84%, 93%, 1);
--Primitive--Green--200: hsla(141, 79%, 85%, 1);
--Primitive--Green--300: hsla(142, 77%, 73%, 1);
--Primitive--Green--400: hsla(142, 69%, 58%, 1);
--Primitive--Green--500: hsla(142, 71%, 45%, 1);
--Primitive--Green--600: hsla(142, 76%, 36%, 1);
--Primitive--Green--700: hsla(142, 72%, 29%, 1);
--Primitive--Green--800: hsla(143, 64%, 24%, 1);
--Primitive--Green--900: hsla(144, 61%, 20%, 1);
--Primitive--Green--950: hsla(145, 80%, 10%, 1);
--Primitive--Emerald--50: hsla(152, 81%, 96%, 1);
--Primitive--Emerald--100: hsla(149, 80%, 90%, 1);
--Primitive--Emerald--200: hsla(152, 76%, 80%, 1);
--Primitive--Emerald--300: hsla(156, 72%, 67%, 1);
--Primitive--Emerald--400: hsla(158, 64%, 52%, 1);
--Primitive--Emerald--500: hsla(160, 84%, 39%, 1);
--Primitive--Emerald--600: hsla(161, 94%, 30%, 1);
--Primitive--Emerald--700: hsla(163, 94%, 24%, 1);
--Primitive--Emerald--800: hsla(163, 88%, 20%, 1);
--Primitive--Emerald--900: hsla(164, 86%, 16%, 1);
--Primitive--Emerald--950: hsla(166, 91%, 9%, 1);
--Primitive--Teal--50: hsla(166, 76%, 97%, 1);
--Primitive--Teal--100: hsla(167, 85%, 89%, 1);
--Primitive--Teal--200: hsla(168, 84%, 78%, 1);
--Primitive--Teal--300: hsla(171, 77%, 64%, 1);
--Primitive--Teal--400: hsla(172, 66%, 50%, 1);
--Primitive--Teal--500: hsla(173, 80%, 40%, 1);
--Primitive--Teal--600: hsla(175, 84%, 32%, 1);
--Primitive--Teal--700: hsla(175, 77%, 26%, 1);
--Primitive--Teal--800: hsla(176, 69%, 22%, 1);
--Primitive--Teal--900: hsla(176, 61%, 19%, 1);
--Primitive--Teal--950: hsla(179, 84%, 10%, 1);
--Primitive--Cyan--50: hsla(183, 100%, 96%, 1);
--Primitive--Cyan--100: hsla(185, 96%, 90%, 1);
--Primitive--Cyan--200: hsla(186, 94%, 82%, 1);
--Primitive--Cyan--300: hsla(187, 92%, 69%, 1);
--Primitive--Cyan--400: hsla(188, 86%, 53%, 1);
--Primitive--Cyan--500: hsla(189, 94%, 43%, 1);
--Primitive--Cyan--600: hsla(192, 91%, 36%, 1);
--Primitive--Cyan--700: hsla(193, 82%, 31%, 1);
--Primitive--Cyan--800: hsla(194, 70%, 27%, 1);
--Primitive--Cyan--900: hsla(196, 64%, 24%, 1);
--Primitive--Cyan--950: hsla(197, 79%, 15%, 1);
--Primitive--Sky--50: hsla(204, 100%, 97%, 1);
--Primitive--Sky--100: hsla(204, 94%, 94%, 1);
--Primitive--Sky--200: hsla(201, 94%, 86%, 1);
--Primitive--Sky--300: hsla(199, 95%, 74%, 1);
--Primitive--Sky--400: hsla(198, 93%, 60%, 1);
--Primitive--Sky--500: hsla(199, 89%, 48%, 1);
--Primitive--Sky--600: hsla(200, 98%, 39%, 1);
--Primitive--Sky--700: hsla(201, 96%, 32%, 1);
--Primitive--Sky--800: hsla(201, 90%, 27%, 1);
--Primitive--Sky--900: hsla(202, 80%, 24%, 1);
--Primitive--Sky--950: hsla(204, 80%, 16%, 1);
--Primitive--Blue--50: hsla(214, 100%, 97%, 1);
--Primitive--Blue--100: hsla(214, 95%, 93%, 1);
--Primitive--Blue--200: hsla(213, 97%, 87%, 1);
--Primitive--Blue--300: hsla(212, 96%, 78%, 1);
--Primitive--Blue--400: hsla(213, 94%, 68%, 1);
--Primitive--Blue--500: hsla(217, 91%, 60%, 1);
--Primitive--Blue--600: hsla(221, 83%, 53%, 1);
--Primitive--Blue--700: hsla(224, 76%, 48%, 1);
--Primitive--Blue--800: hsla(226, 71%, 40%, 1);
--Primitive--Blue--900: hsla(224, 64%, 33%, 1);
--Primitive--Blue--950: hsla(226, 57%, 21%, 1);
--Primitive--Indigo--50: hsla(226, 100%, 97%, 1);
--Primitive--Indigo--100: hsla(226, 100%, 94%, 1);
--Primitive--Indigo--200: hsla(228, 96%, 89%, 1);
--Primitive--Indigo--300: hsla(230, 94%, 82%, 1);
--Primitive--Indigo--400: hsla(234, 89%, 74%, 1);
--Primitive--Indigo--500: hsla(239, 84%, 67%, 1);
--Primitive--Indigo--600: hsla(243, 75%, 59%, 1);
--Primitive--Indigo--700: hsla(245, 58%, 51%, 1);
--Primitive--Indigo--800: hsla(244, 55%, 41%, 1);
--Primitive--Indigo--900: hsla(242, 47%, 34%, 1);
--Primitive--Indigo--950: hsla(244, 47%, 20%, 1);
--Primitive--Violet--50: hsla(250, 100%, 98%, 1);
--Primitive--Violet--100: hsla(251, 91%, 95%, 1);
--Primitive--Violet--200: hsla(251, 95%, 92%, 1);
--Primitive--Violet--300: hsla(253, 95%, 85%, 1);
--Primitive--Violet--400: hsla(255, 92%, 76%, 1);
--Primitive--Violet--500: hsla(258, 90%, 66%, 1);
--Primitive--Violet--600: hsla(262, 83%, 58%, 1);
--Primitive--Violet--700: hsla(263, 70%, 50%, 1);
--Primitive--Violet--800: hsla(263, 69%, 42%, 1);
--Primitive--Violet--900: hsla(264, 67%, 35%, 1);
--Primitive--Violet--950: hsla(262, 78%, 23%, 1);
--Primitive--Purple--50: hsla(270, 100%, 98%, 1);
--Primitive--Purple--100: hsla(269, 100%, 95%, 1);
--Primitive--Purple--200: hsla(269, 100%, 92%, 1);
--Primitive--Purple--300: hsla(269, 97%, 85%, 1);
--Primitive--Purple--400: hsla(270, 95%, 75%, 1);
--Primitive--Purple--500: hsla(271, 91%, 65%, 1);
--Primitive--Purple--600: hsla(271, 81%, 56%, 1);
--Primitive--Purple--700: hsla(272, 72%, 47%, 1);
--Primitive--Purple--800: hsla(273, 67%, 39%, 1);
--Primitive--Purple--900: hsla(274, 66%, 32%, 1);
--Primitive--Purple--950: hsla(274, 87%, 21%, 1);
--Primitive--Fuchsia--50: hsla(289, 100%, 98%, 1);
--Primitive--Fuchsia--100: hsla(287, 100%, 95%, 1);
--Primitive--Fuchsia--200: hsla(288, 96%, 91%, 1);
--Primitive--Fuchsia--300: hsla(291, 93%, 83%, 1);
--Primitive--Fuchsia--400: hsla(292, 91%, 73%, 1);
--Primitive--Fuchsia--500: hsla(292, 84%, 61%, 1);
--Primitive--Fuchsia--600: hsla(293, 69%, 49%, 1);
--Primitive--Fuchsia--700: hsla(295, 72%, 40%, 1);
--Primitive--Fuchsia--800: hsla(295, 70%, 33%, 1);
--Primitive--Fuchsia--900: hsla(297, 64%, 28%, 1);
--Primitive--Fuchsia--950: hsla(297, 90%, 16%, 1);
--Primitive--Pink--50: hsla(327, 73%, 97%, 1);
--Primitive--Pink--100: hsla(326, 78%, 95%, 1);
--Primitive--Pink--200: hsla(326, 85%, 90%, 1);
--Primitive--Pink--300: hsla(327, 87%, 82%, 1);
--Primitive--Pink--400: hsla(329, 86%, 70%, 1);
--Primitive--Pink--500: hsla(330, 81%, 60%, 1);
--Primitive--Pink--600: hsla(333, 71%, 51%, 1);
--Primitive--Pink--700: hsla(335, 78%, 42%, 1);
--Primitive--Pink--800: hsla(336, 74%, 35%, 1);
--Primitive--Pink--900: hsla(336, 69%, 30%, 1);
--Primitive--Pink--950: hsla(336, 84%, 17%, 1);
--Primitive--Rose--50: hsla(356, 100%, 97%, 1);
--Primitive--Rose--100: hsla(356, 100%, 95%, 1);
--Primitive--Rose--200: hsla(353, 96%, 90%, 1);
--Primitive--Rose--300: hsla(353, 96%, 82%, 1);
--Primitive--Rose--400: hsla(351, 95%, 71%, 1);
--Primitive--Rose--500: hsla(350, 89%, 60%, 1);
--Primitive--Rose--600: hsla(347, 77%, 50%, 1);
--Primitive--Rose--700: hsla(345, 83%, 41%, 1);
--Primitive--Rose--800: hsla(343, 80%, 35%, 1);
--Primitive--Rose--900: hsla(342, 75%, 30%, 1);
--Primitive--Rose--950: hsla(343, 88%, 16%, 1);
--Brand--Base_Colors--Destructive: var(--Primitive--Red--500);
--Brand--Base_Colors--Success: var(--Primitive--Green--500);
--Brand--Base_Colors--Warning: var(--Primitive--Amber--500);
--Brand--Base_Colors--White: var(--Primitive--White);
--Brand--Base_Colors--Black: var(--Primitive--Black);
--Brand--Semantic_Colors--Background: var(--Primitive--Zinc--900); /*页面背景色:应用在整个页面的最底层。*/
--Brand--Semantic_Colors--Background-subtle: hsla(
0,
0%,
100%,
0.02
); /*细微背景色:用于需要与主背景有微弱区分的区域,如代码块背景。*/
--Brand--Semantic_Colors--Foreground: hsla(0, 0%, 100%, 0.9); /*主要前景/文字色:用于正文、标题等。*/
--Brand--Semantic_Colors--Foreground-secondary: hsla(0, 0%, 100%, 0.6); /*次要前景/文字色:用于辅助性文本、描述。*/
--Brand--Semantic_Colors--Foreground-muted: hsla(0, 0%, 100%, 0.4); /*静默前景/文字色:用于禁用状态的文字、占位符。*/
--Brand--Semantic_Colors--Border: hsla(0, 0%, 100%, 0.1); /*默认边框色:用于卡片、输入框、分隔线。*/
--Brand--Semantic_Colors--Border-hover: hsla(0, 0%, 100%, 0.2); /*激活边框色:用于元素被按下或激活时的边框。*/
--Brand--Semantic_Colors--Border-active: hsla(0, 0%, 100%, 0.3); /*激活边框色:用于元素被按下或激活时的边框。*/
--Brand--Semantic_Colors--Ring: hsla(
84,
81%,
44%,
0.4
); /*聚焦环颜色:用于输入框等元素在聚焦 (Focus) 状态下的外发光。*/
--Brand--UI_Element_Colors--Modal--Backdrop: hsla(0, 0%, 0%, 0.06);
--Brand--UI_Element_Colors--Modal--Thumb: hsla(0, 0%, 100%, 0.2);
--Brand--UI_Element_Colors--Modal--Thumb_Hover: hsla(0, 0%, 100%, 0.3);
--Brand--UI_Element_Colors--Icon--Default: var(--Brand--Semantic_Colors--Foreground-secondary);
--Brand--UI_Element_Colors--Icon--Hover: var(--Brand--Semantic_Colors--Foreground);
--Brand--UI_Element_Colors--Input_Select--Background: var(--Brand--Base_Colors--Black);
--Brand--UI_Element_Colors--Input_Select--Border: var(--Brand--Semantic_Colors--Border);
--Brand--UI_Element_Colors--Input_Select--Border_Hover: var(--Brand--Semantic_Colors--Border-hover);
--Brand--UI_Element_Colors--Input_Select--Border_Focus: var(--Brand--Base_Colors--Primary);
--Brand--UI_Element_Colors--Primary_Button--Background: var(--Brand--Base_Colors--Primary);
--Brand--UI_Element_Colors--Card_Container--Background: var(--Brand--Base_Colors--Black);
--Brand--UI_Element_Colors--Card_Container--Border: var(--Brand--Semantic_Colors--Border);
--Brand--UI_Element_Colors--Ghost_Button--Background: hsla(0, 0%, 100%, 0);
--Brand--UI_Element_Colors--Ghost_Button--Text: var(--Brand--Semantic_Colors--Foreground);
--Brand--UI_Element_Colors--Ghost_Button--Background_Hover: var(--Opacity--White--White-10);
--Brand--UI_Element_Colors--Ghost_Button--Background_Active: hsla(0, 0%, 100%, 0.15);
--Brand--UI_Element_Colors--Secondary_Button--Background: var(--Opacity--White--White-10);
--Brand--UI_Element_Colors--Secondary_Button--Text: var(--Brand--Semantic_Colors--Foreground);
--Brand--UI_Element_Colors--Secondary_Button--Background_Hover: var(--Opacity--White--White-20);
--Brand--UI_Element_Colors--Secondary_Button--Background_Active: hsla(0, 0%, 100%, 0.25);
--Brand--UI_Element_Colors--Secondary_Button--Border: var(--Brand--Semantic_Colors--Border);
--Brand--UI_Element_Colors--Primary_Button--Text: var(--Brand--Base_Colors--White);
--Brand--UI_Element_Colors--Primary_Button--Background_Hover: hsla(84, 81%, 44%, 0.85);
--Brand--UI_Element_Colors--Primary_Button--2nd_Background: hsla(84, 81%, 44%, 0.1);
--Brand--UI_Element_Colors--Primary_Button--3rd_Background: hsla(84, 81%, 44%, 0.05);
--Brand--UI_Element_Colors--Primary_Button--Background_Active: hsla(84, 81%, 44%, 0.7);
--Boolean: false;
}

View File

@@ -0,0 +1,12 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1002_325032)">
<path d="M13.1591 23.9994C19.1463 23.9994 23.9999 19.1369 23.9999 13.1387C23.9999 7.14056 19.1463 2.27808 13.1591 2.27808C7.17194 2.27808 2.31836 7.14056 2.31836 13.1387C2.31836 19.1369 7.17194 23.9994 13.1591 23.9994Z" fill="#3F3FAA"/>
<path d="M10.8408 21.7213C16.828 21.7213 21.6816 16.8589 21.6816 10.8607C21.6816 4.86249 16.828 0 10.8408 0C4.85358 0 0 4.86249 0 10.8607C0 16.8589 4.85358 21.7213 10.8408 21.7213Z" fill="#8E47F0"/>
<path d="M10.674 18.0887C9.90386 18.0887 9.15988 17.8338 8.5431 17.3518C7.81081 16.7798 7.34412 15.9557 7.23049 15.0323C7.19589 14.7503 7.19449 14.4706 7.22628 14.1956C7.01212 14.2373 6.79047 14.2589 6.56461 14.2589C4.64737 14.2589 3.0874 12.696 3.0874 10.7753C3.0874 8.85455 4.64737 7.29172 6.56461 7.29172C6.83863 7.29172 7.10564 7.32357 7.36143 7.38401C7.34646 7.25283 7.33898 7.11979 7.33898 6.98627C7.33898 5.06552 8.89895 3.50269 10.8162 3.50269C12.7334 3.50269 14.2934 5.06552 14.2934 6.98627C14.2934 7.09777 14.2882 7.2088 14.2775 7.31936C14.559 7.27017 14.848 7.25517 15.1393 7.27719C17.0514 7.41914 18.4917 9.09347 18.35 11.0091C18.2812 11.9371 17.8557 12.7827 17.1524 13.3903C16.4486 13.9979 15.5503 14.295 14.6249 14.2256C14.4566 14.213 14.2911 14.1886 14.1293 14.153C14.1302 14.161 14.1311 14.1689 14.1325 14.1769C14.2466 15.1003 13.995 16.0129 13.4241 16.747C12.8531 17.4811 12.0306 17.9481 11.1089 18.0624C10.9635 18.0802 10.8185 18.0891 10.6745 18.0891L10.674 18.0887ZM8.74417 13.4878C8.50008 13.9113 8.40328 14.3915 8.4636 14.8796C8.53702 15.4732 8.83629 16.0025 9.30718 16.3698C9.77761 16.7376 10.3631 16.8997 10.9555 16.8261C11.548 16.7526 12.0764 16.4528 12.443 15.981C12.8101 15.5092 12.9719 14.9227 12.8985 14.3296C12.8503 13.938 12.7016 13.5702 12.4669 13.2587C12.3135 13.1102 12.1732 12.9472 12.0474 12.7696C11.8487 12.4895 11.9142 12.1006 12.1938 11.9015C12.4734 11.7019 12.8615 11.768 13.0603 12.0477C13.1066 12.1128 13.1557 12.1751 13.208 12.2341C13.2497 12.2636 13.2885 12.2988 13.3236 12.3391C13.3446 12.3639 13.3656 12.3887 13.3857 12.414C13.7505 12.7443 14.2162 12.9462 14.7166 12.9832C15.9483 13.0755 17.0191 12.1475 17.1103 10.9163C17.2015 9.68516 16.2761 8.60954 15.0472 8.51818C14.5763 8.48305 14.1166 8.59455 13.7159 8.8405C13.5256 8.99697 13.252 9.03117 13.0229 8.90515C12.7222 8.73977 12.6118 8.36125 12.7769 8.06002C12.956 7.73302 13.0505 7.36152 13.0505 6.9858C13.0505 5.75137 12.0479 4.74696 10.8157 4.74696C9.58354 4.74696 8.58097 5.75137 8.58097 6.9858C8.58097 7.42757 8.7091 7.85435 8.95133 8.2207C8.96302 8.2385 8.97377 8.25677 8.98359 8.27551C9.63545 8.90889 10.0409 9.79572 10.0409 10.7753C10.0409 11.8701 9.53444 12.8483 8.7437 13.4873L8.74417 13.4878ZM6.56414 8.53692C5.33197 8.53692 4.32939 9.54134 4.32939 10.7758C4.32939 12.0102 5.33197 13.0146 6.56414 13.0146C7.79631 13.0146 8.79888 12.0102 8.79888 10.7758C8.79888 9.54134 7.79631 8.53692 6.56414 8.53692Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1002_325032">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.9 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 140 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1010_212037)">
<path d="M19.5 0H4.5C2.01472 0 0 2.01472 0 4.5V19.5C0 21.9853 2.01472 24 4.5 24H19.5C21.9853 24 24 21.9853 24 19.5V4.5C24 2.01472 21.9853 0 19.5 0Z" fill="#333333"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.5423 4.71087C5.21065 6.81312 11.4721 19.8057 11.8942 19.8746C12.246 19.9436 17.0652 10.156 19.4923 4.40071C19.5627 4.26285 19.1406 4.125 18.5426 4.125C17.7335 4.125 17.4521 4.29732 17.4521 4.71087C17.4521 5.26228 12.457 17.2899 12.3163 17.1176C12.0349 16.7385 7.2509 5.77923 7.07501 5.0555C6.86395 4.26285 6.65289 4.125 5.5976 4.125C4.57748 4.125 4.40159 4.22839 4.5423 4.71087Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1010_212037">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 866 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,15 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1002_325038)">
<path d="M21.8843 0H2.07031C0.965743 0 0.0703125 0.89543 0.0703125 2V22C0.0703125 23.1046 0.965742 24 2.07031 24H21.8843C22.9888 24 23.8843 23.1046 23.8843 22V2C23.8843 0.895431 22.9888 0 21.8843 0Z" fill="url(#paint0_linear_1002_325038)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.2237 8.39297C11.3167 7.74923 11.5229 6.92265 11.8423 5.91328C11.8846 5.78242 12.0698 5.78242 12.1121 5.91328C12.4315 6.92265 12.6377 7.74923 12.7307 8.39297C12.802 8.86485 12.802 9.46485 12.7307 10.193C12.6594 10.9242 12.6594 11.5289 12.7307 12.007C12.8361 12.707 13.154 13.2883 13.6842 13.7508C14.2237 14.2227 14.8485 14.4586 15.5586 14.4586C16.3462 14.4586 17.0191 14.1789 17.5772 13.6195C18.1322 13.0602 18.4129 12.3852 18.4191 11.5945C18.4222 10.8945 18.4935 10.1227 18.6331 9.27891C18.7012 8.85703 18.7709 8.50391 18.8424 8.21953C18.8731 8.09239 19.0472 8.07302 19.1028 8.19141C19.5834 9.21641 19.8346 10.2976 19.8563 11.4352V11.5945C19.8563 12.6727 19.65 13.7023 19.2377 14.6836C18.8377 15.6367 18.2749 16.4789 17.5493 17.2102C16.8206 17.9414 15.985 18.5086 15.0423 18.9118C14.0687 19.3273 13.047 19.5353 11.9772 19.5353C10.9074 19.5353 9.88574 19.3273 8.9121 18.9118C7.96946 18.5086 7.13381 17.9414 6.40512 17.2102C5.67954 16.4789 5.11675 15.6367 4.71675 14.6836C4.30434 13.7023 4.09814 12.6727 4.09814 11.5945V11.4352C4.11986 10.2976 4.37102 9.21641 4.85163 8.19141C4.90728 8.07302 5.08133 8.09239 5.1121 8.21953C5.18341 8.50391 5.25318 8.85703 5.3214 9.27891C5.46094 10.1227 5.53225 10.8945 5.53535 11.5945C5.54155 12.3852 5.82218 13.0602 6.37721 13.6195C6.93535 14.1789 7.60823 14.4586 8.39582 14.4586C9.1059 14.4586 9.7307 14.2227 10.2702 13.7508C10.8005 13.2883 11.1183 12.707 11.2237 12.007C11.295 11.5289 11.295 10.9242 11.2237 10.193C11.1524 9.46485 11.1524 8.86485 11.2237 8.39297ZM11.9772 18.0867C13.0656 18.0867 14.0857 17.8273 15.0377 17.3086C15.7123 16.9427 16.2981 16.4766 16.7952 15.9103C16.8573 15.8397 16.7842 15.7321 16.6938 15.7568C16.3276 15.857 15.9492 15.907 15.5586 15.907C14.7834 15.907 14.0625 15.7102 13.3958 15.3164C12.8571 15 12.4108 14.5891 12.0568 14.0839C12.0182 14.0289 11.9362 14.0289 11.8977 14.0839C11.5437 14.5891 11.0973 15 10.5586 15.3164C9.89195 15.7102 9.17102 15.907 8.39582 15.907C8.00523 15.907 7.62685 15.857 7.26064 15.7568C7.17029 15.7321 7.0972 15.8397 7.1592 15.9103C7.65628 16.4766 8.24213 16.9427 8.91675 17.3086C9.86869 17.8273 10.8888 18.0867 11.9772 18.0867Z" fill="white"/>
</g>
<defs>
<linearGradient id="paint0_linear_1002_325038" x1="11.9773" y1="0" x2="11.9773" y2="24" gradientUnits="userSpaceOnUse">
<stop stop-color="#2563EB"/>
<stop offset="1" stop-color="#0049DF"/>
</linearGradient>
<clipPath id="clip0_1002_325038">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1010_212036)">
<path d="M18 0H6C2.68629 0 0 2.68629 0 6V18C0 21.3137 2.68629 24 6 24H18C21.3137 24 24 21.3137 24 18V6C24 2.68629 21.3137 0 18 0Z" fill="#CA9F7B"/>
<path d="M15.3843 6.43481H12.9687L17.3739 17.5652H19.7896L15.3843 6.43481ZM8.40522 6.43481L4 17.5652H6.4633L7.36417 15.2279H11.9729L12.8737 17.5652H15.337L10.9318 6.43481H8.40522ZM8.16104 13.1607L9.66852 9.24907L11.176 13.1607H8.16104Z" fill="#191918"/>
</g>
<defs>
<clipPath id="clip0_1010_212036">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 655 B

View File

@@ -0,0 +1,20 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1002_325036)">
<mask id="mask0_1002_325036" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24">
<path d="M24 0H0V24H24V0Z" fill="white"/>
</mask>
<g mask="url(#mask0_1002_325036)">
<path d="M19 0H4.99999C2.23857 0 0 2.23857 0 4.99999V19C0 21.7614 2.23857 24 4.99999 24H19C21.7614 24 24 21.7614 24 19V4.99999C24 2.23857 21.7614 0 19 0Z" fill="url(#paint0_linear_1002_325036)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9995 18.1395L9.57351 18.9485L8.62752 18.3174L9.65751 17.9734L9.34152 17.0254L7.57352 17.6145L6.99951 17.2325V14.4995C6.99951 14.3105 6.89252 14.1375 6.72351 14.0525L4.99952 13.1905V10.8085L6.49952 10.0585L7.99952 10.8085V12.4995C7.99952 12.6895 8.10651 12.8625 8.27552 12.9475L10.2755 13.9475L10.7235 13.0525L8.99952 12.1905V10.8085L10.7235 9.94746C10.8925 9.86245 10.9995 9.68946 10.9995 9.49946V7.99946H9.99951V9.19045L8.49951 9.94045L6.99951 9.19045V6.76746L7.99952 6.10045V7.99946H8.99952V5.43445L9.57351 5.05146L11.9995 5.86045V18.1395ZM17.4995 16.9995C17.7745 16.9995 17.9995 17.2234 17.9995 17.4994C17.9995 17.7754 17.7745 17.9994 17.4995 17.9994C17.2246 17.9994 16.9996 17.7754 16.9996 17.4994C16.9996 17.2234 17.2246 16.9995 17.4995 16.9995ZM16.4995 5.99946C16.7746 5.99946 16.9996 6.22345 16.9996 6.49945C16.9996 6.77545 16.7746 6.99945 16.4995 6.99945C16.2245 6.99945 15.9995 6.77545 15.9995 6.49945C15.9995 6.22345 16.2245 5.99946 16.4995 5.99946ZM18.4996 11.9995C18.7745 11.9995 18.9995 12.2235 18.9995 12.4995C18.9995 12.7755 18.7745 12.9995 18.4996 12.9995C18.2245 12.9995 17.9995 12.7755 17.9995 12.4995C17.9995 12.2235 18.2245 11.9995 18.4996 11.9995ZM17.0915 12.9995C17.2985 13.5805 17.8486 13.9995 18.4996 13.9995C19.3265 13.9995 19.9996 13.3275 19.9996 12.4995C19.9996 11.6725 19.3265 10.9995 18.4996 10.9995C17.8486 10.9995 17.2985 11.4195 17.0915 11.9995H12.9995V9.99946H16.4995C16.7755 9.99946 16.9996 9.77646 16.9996 9.49946V7.90746C17.5805 7.70046 17.9995 7.15045 17.9995 6.49945C17.9995 5.67246 17.3266 4.99945 16.4995 4.99945C15.6725 4.99945 14.9995 5.67246 14.9995 6.49945C14.9995 7.15045 15.4186 7.70046 15.9995 7.90746V8.99946H12.9995V5.49945C12.9995 5.28445 12.8615 5.09346 12.6575 5.02545L9.65751 4.02546C9.51051 3.97645 9.35052 3.99846 9.22251 4.08345L6.22251 6.08346C6.08352 6.17646 5.99952 6.33246 5.99952 6.49945V9.19045L4.27551 10.0525C4.10652 10.1375 3.99951 10.3105 3.99951 10.4995V13.4995C3.99951 13.6895 4.10652 13.8625 4.27551 13.9475L5.99952 14.8085V17.4994C5.99952 17.6664 6.08352 17.8234 6.22251 17.9154L9.22251 19.9155C9.30552 19.9715 9.40152 19.9995 9.49952 19.9995C9.55251 19.9995 9.60552 19.9914 9.65751 19.9734L12.6575 18.9735C12.8615 18.9065 12.9995 18.7155 12.9995 18.4995V15.9994H15.2926L16.1455 16.8534L16.1585 16.8405C16.0606 17.0405 15.9995 17.2624 15.9995 17.4994C15.9995 18.3264 16.6726 18.9994 17.4995 18.9994C18.3265 18.9994 18.9995 18.3264 18.9995 17.4994C18.9995 16.6725 18.3265 15.9994 17.4995 15.9994C17.2615 15.9994 17.0395 16.0605 16.8406 16.1595L16.8535 16.1465L15.8536 15.1464C15.7595 15.0525 15.6325 14.9995 15.4996 14.9995H12.9995V12.9995H17.0915Z" fill="white"/>
</g>
</g>
<defs>
<linearGradient id="paint0_linear_1002_325036" x1="0" y1="2400" x2="2400" y2="0" gradientUnits="userSpaceOnUse">
<stop stop-color="#055F4E"/>
<stop offset="1" stop-color="#56C0A7"/>
</linearGradient>
<clipPath id="clip0_1002_325036">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,49 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1012_212067)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2329 0C16.9459 0 17.5779 0.551 17.8049 1.329C18.0319 2.107 19.3599 6.919 19.3599 6.919V16.481H14.5469L14.6449 0H16.2329Z" fill="url(#paint0_linear_1012_212067)"/>
<path d="M23.298 7.47012C23.298 7.13012 23.023 6.87012 22.698 6.87012H19.863C18.9046 6.87091 17.9857 7.25206 17.3081 7.92986C16.6305 8.60767 16.2496 9.5267 16.249 10.4851V16.4811H19.685C20.6431 16.4801 21.5616 16.0989 22.239 15.4214C22.9164 14.7438 23.2972 13.8252 23.298 12.8671V7.47012Z" fill="url(#paint1_linear_1012_212067)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.233 2.5131e-05C16.1028 -0.00090588 15.9738 0.0240397 15.8534 0.0734119C15.733 0.122784 15.6236 0.195598 15.5316 0.287621C15.4395 0.379644 15.3667 0.489041 15.3173 0.609452C15.268 0.729864 15.243 0.858888 15.244 0.989025L15.147 19.187C15.1467 20.4634 14.6395 21.6875 13.737 22.59C12.8344 23.4926 11.6104 23.9998 10.334 24H1.59996C1.50434 24.0006 1.40998 23.9782 1.32484 23.9346C1.23969 23.8911 1.16624 23.8278 1.11067 23.75C1.0551 23.6722 1.01904 23.5821 1.00551 23.4875C0.991989 23.3928 1.0014 23.2963 1.03296 23.206L8.03296 3.22502C8.36272 2.2842 8.97615 1.4688 9.78873 0.891207C10.6013 0.313611 11.573 0.00224754 12.57 2.5131e-05H16.249H16.233Z" fill="url(#paint2_linear_1012_212067)"/>
</g>
<defs>
<linearGradient id="paint0_linear_1012_212067" x1="18.2419" y1="16.837" x2="14.1909" y2="0.616" gradientUnits="userSpaceOnUse">
<stop stop-color="#712575"/>
<stop offset="0.09" stop-color="#9A2884"/>
<stop offset="0.18" stop-color="#BF2C92"/>
<stop offset="0.27" stop-color="#DA2E9C"/>
<stop offset="0.34" stop-color="#EB30A2"/>
<stop offset="0.4" stop-color="#F131A5"/>
<stop offset="0.5" stop-color="#EC30A3"/>
<stop offset="0.61" stop-color="#DF2F9E"/>
<stop offset="0.72" stop-color="#C92D96"/>
<stop offset="0.83" stop-color="#AA2A8A"/>
<stop offset="0.95" stop-color="#83267C"/>
<stop offset="1" stop-color="#712575"/>
</linearGradient>
<linearGradient id="paint1_linear_1012_212067" x1="19.782" y1="0.340117" x2="19.782" y2="23.2221" gradientUnits="userSpaceOnUse">
<stop stop-color="#DA7ED0"/>
<stop offset="0.08" stop-color="#B17BD5"/>
<stop offset="0.19" stop-color="#8778DB"/>
<stop offset="0.3" stop-color="#6276E1"/>
<stop offset="0.41" stop-color="#4574E5"/>
<stop offset="0.54" stop-color="#2E72E8"/>
<stop offset="0.67" stop-color="#1D71EB"/>
<stop offset="0.81" stop-color="#1471EC"/>
<stop offset="1" stop-color="#1171ED"/>
</linearGradient>
<linearGradient id="paint2_linear_1012_212067" x1="18.404" y1="0.859025" x2="3.23596" y2="25.183" gradientUnits="userSpaceOnUse">
<stop stop-color="#DA7ED0"/>
<stop offset="0.05" stop-color="#B77BD4"/>
<stop offset="0.11" stop-color="#9079DA"/>
<stop offset="0.18" stop-color="#6E77DF"/>
<stop offset="0.25" stop-color="#5175E3"/>
<stop offset="0.33" stop-color="#3973E7"/>
<stop offset="0.42" stop-color="#2772E9"/>
<stop offset="0.54" stop-color="#1A71EB"/>
<stop offset="0.68" stop-color="#1371EC"/>
<stop offset="1" stop-color="#1171ED"/>
</linearGradient>
<clipPath id="clip0_1012_212067">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,9 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.58154 1.7793H5.52779L3.34655 6.20409V17.7335L0.916016 22.2206H6.21333L8.58154 17.7335V1.7793ZM10.5761 1.7793H15.8111V22.2206H10.5761V1.7793ZM22.9166 1.7793H17.6816V6.01712H22.9166V1.7793ZM22.9166 7.38818H17.6816V22.2206H22.9166V7.38818Z" fill="url(#paint0_radial_1002_325039)"/>
<defs>
<radialGradient id="paint0_radial_1002_325039" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(5.5 5.5) rotate(45) scale(20.5061 22.0704)">
<stop stop-color="#FEBD3F"/>
<stop offset="0.77608" stop-color="#FF6933"/>
</radialGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 714 B

View File

@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21.7149 5.61L17.7319 7.92C17.5954 7.99796 17.441 8.03897 17.2839 8.03897C17.1267 8.03897 16.9723 7.99796 16.8359 7.92L12.4399 5.384C12.3033 5.30585 12.1487 5.26475 11.9914 5.26475C11.834 5.26475 11.6794 5.30585 11.5429 5.384L7.15588 7.92C7.01944 7.99796 6.86502 8.03897 6.70788 8.03897C6.55074 8.03897 6.39632 7.99796 6.25988 7.92L2.27588 5.617L12.0019 0L21.7149 5.61Z" fill="#5BCA87"/>
<path d="M18.6408 9.46698C18.5069 9.54591 18.3961 9.65853 18.3192 9.79362C18.2424 9.92871 18.2022 10.0816 18.2028 10.237V15.309C18.2021 15.465 18.1606 15.618 18.0826 15.7531C18.0045 15.8881 17.8926 16.0005 17.7578 16.079L13.3298 18.589C13.1932 18.6671 13.0799 18.7804 13.0017 18.917C12.9234 19.0536 12.8831 19.2086 12.8848 19.366V23.973L17.3138 21.437L22.6238 18.39V7.15698L18.6408 9.46698Z" fill="#EC5D3E"/>
<path d="M10.9799 18.941C10.9095 18.7998 10.8046 18.6787 10.6749 18.589L6.24588 16.073C6.11503 15.9927 6.00679 15.8805 5.93138 15.7468C5.85597 15.6131 5.81587 15.4624 5.81488 15.309V10.231C5.81178 10.0764 5.76847 9.92529 5.68921 9.79255C5.60995 9.65982 5.49748 9.55001 5.36288 9.47396L4.91188 9.21396L1.37988 7.15796V18.39L6.69088 21.437L11.1259 24V19.392C11.1192 19.2315 11.0687 19.0748 10.9799 18.941Z" fill="#2464F5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,9 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.33594 8.91895V15.0809L11.6709 11.9979L6.33694 8.91995L6.33594 8.91895Z" fill="#1C54E3"/>
<path d="M21.3939 5.28791C21.3939 5.28791 21.3879 5.28191 21.3839 5.28191L17.0099 2.75391L6.33594 8.91991L11.6709 12.0019L21.3719 6.40191L21.3879 6.39191C21.4848 6.33671 21.5654 6.25698 21.6217 6.16074C21.678 6.0645 21.708 5.95513 21.7086 5.84364C21.7092 5.73215 21.6804 5.62246 21.6252 5.52561C21.57 5.42876 21.4902 5.34815 21.3939 5.29191V5.28791Z" fill="#AA9AFF"/>
<path d="M21.7098 12.4651C21.5987 12.4646 21.4896 12.494 21.3938 12.5501C21.3938 12.5501 21.3878 12.5501 21.3848 12.5531L17.0098 15.0811L22.0598 17.9961H22.0658C22.2497 17.6804 22.3463 17.3215 22.3458 16.9561V13.1011C22.3455 12.9325 22.2784 12.7709 22.1592 12.6517C22.04 12.5324 21.8784 12.4654 21.7098 12.4651Z" fill="#00EAD1"/>
<path d="M22.0598 17.9961L17.0098 15.0811L6.33984 21.2421L10.6098 23.7071C10.6098 23.7071 10.6258 23.7131 10.6318 23.7191C10.9503 23.9019 11.3111 23.9981 11.6783 23.9981C12.0456 23.9981 12.4064 23.9019 12.7248 23.7191C12.7308 23.7161 12.7408 23.7131 12.7468 23.7071L21.2848 18.7771C21.2878 18.7771 21.2908 18.7741 21.2948 18.7711C21.6158 18.5881 21.8838 18.3211 22.0698 17.9991H22.0638L22.0598 17.9961Z" fill="#00CEC9"/>
<path d="M11.6718 11.998L6.33578 15.081L4.89179 15.913L1.28679 17.996H1.27979C1.45279 18.299 1.69579 18.551 1.98879 18.734L2.06679 18.778L2.08279 18.788L2.10279 18.8L6.33479 21.242L17.0058 15.081L11.6708 11.999L11.6718 11.998Z" fill="#00EAD1"/>
<path d="M12.7398 0.29C12.6398 0.23 12.5318 0.183 12.4248 0.142C12.4048 0.136 12.3868 0.126 12.3678 0.12C12.1428 0.0409411 11.9062 0.000372506 11.6678 0C11.4348 0 11.2108 0.038 10.9998 0.11L10.9688 0.12C10.8397 0.164971 10.7152 0.221884 10.5968 0.29L2.06776 5.222C2.06776 5.222 2.06476 5.222 2.06176 5.225C1.73776 5.408 1.46976 5.676 1.28076 5.998H1.28676L6.33576 8.916L17.0098 2.758L12.7398 0.29Z" fill="#7347FF"/>
<path d="M1.287 6.00098H1.28C1.09609 6.31668 0.999456 6.67561 1 7.04098V16.956C1 17.334 1.1 17.691 1.28 17.999H1.287L6.336 15.081V8.91898L1.287 6.00098Z" fill="#0423DA"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.03564 5.23655C4.98434 4.28649 7.33391 5.09586 8.28487 7.04481L10.3152 11.2059C10.7903 12.1795 10.3865 13.3541 9.41333 13.8293C9.41293 13.8295 9.41253 13.8297 9.41213 13.8299C8.43778 14.3049 7.26299 13.9003 6.78749 12.9258L3.03564 5.23655Z" fill="#A5CCFF"/>
<path opacity="0.64774" fill-rule="evenodd" clip-rule="evenodd" d="M1 9.20141C2.53317 7.66887 5.0175 7.66887 6.55069 9.20141L9.94604 12.5954C10.7118 13.3607 10.7123 14.6023 9.94724 15.3683C9.94684 15.3687 9.94644 15.3691 9.94604 15.3695C9.17949 16.1358 7.93729 16.1358 7.17069 15.3695L1 9.20141Z" fill="#A5CCFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.0666 5.92163C19.4481 5.92163 23 9.47209 23 13.8518C23 15.99 21.9007 18.1627 20.5242 19.589L19.9543 18.9058C18.9766 17.734 18.6294 16.1599 19.0233 14.6853C19.0946 14.418 19.1303 14.1725 19.1303 13.9487C19.1303 11.6897 17.2983 9.85839 15.0383 9.85839C12.7785 9.85839 10.9464 11.6897 10.9464 13.9487C10.9464 16.2076 12.7785 18.0389 15.0383 18.0389C15.4614 18.0389 15.8695 17.9747 16.2534 17.8556C17.4037 17.4985 18.6572 17.795 19.5259 18.6297L20.5242 19.589C19.1068 20.9118 17.1588 21.7818 15.0666 21.7818C10.6852 21.7818 7.1333 18.2314 7.1333 13.8518C7.1333 9.47209 10.6852 5.92163 15.0666 5.92163Z" fill="#006EFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.1333 3C9.30097 3 11.0582 4.75808 11.0582 6.9267V9.75804C11.0582 11.9267 9.30097 13.6847 7.1333 13.6847V3Z" fill="#006EFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.9442 18.587L13.2402 18.142V10.01L15.0642 9.54795C16.0642 9.29395 16.9042 9.08695 16.9442 9.09495C16.9762 9.09495 17.0002 11.33 17.0002 14.067V19.04L16.8242 19.0319C16.7202 19.0319 15.8722 18.826 14.9442 18.587Z" fill="#00C8D2"/>
<path d="M7 16.542C7 13.806 7.024 11.562 7.064 11.562C7.096 11.554 7.936 11.762 8.944 12.016L10.76 12.477L10.744 16.527L10.72 20.576L9.088 20.998C8.192 21.228 7.352 21.443 7.232 21.467L7 21.523V16.542Z" fill="#3C8CFF"/>
<path d="M19.2402 12.477C19.2402 3.44697 19.2482 2.96197 19.3842 3.00197C19.4562 3.02597 20.1682 3.20897 20.9602 3.40797C21.7522 3.61497 22.5362 3.81297 22.7042 3.85297L23.0002 3.93297L22.9842 12.493L22.9602 21.061L21.3362 21.475C20.4482 21.705 19.6082 21.912 19.4802 21.945L19.2402 22V12.477Z" fill="#78E6DC"/>
<path d="M1 12.5089C1 7.83091 1.024 4.00391 1.064 4.00391C1.096 4.00391 1.936 4.21091 2.936 4.45791L4.76 4.91891V12.5009C4.76 16.6609 4.744 20.0749 4.728 20.0749C4.704 20.0749 3.856 20.2899 2.848 20.5449L1 21.0129V12.5089Z" fill="#325AB4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9681 5.37441C12.0144 5.46932 12.037 5.57421 12.0336 5.67911C12.0295 5.80735 12.0554 5.9348 12.1093 6.05175C12.1631 6.1687 12.2435 6.27206 12.3443 6.35396C12.4451 6.43585 12.5636 6.49413 12.6909 6.52433C12.8181 6.55454 12.9508 6.55588 13.0786 6.52826L19.6465 5.10635C19.9293 5.04511 20.2227 5.04687 20.5048 5.11149C20.7869 5.1761 21.0506 5.30193 21.2764 5.4797C21.5023 5.65746 21.6846 5.88263 21.8098 6.13859C21.935 6.39456 22 6.67481 22 6.95867V16.8576C22 17.4258 21.7696 17.9707 21.3596 18.3725C20.9495 18.7743 20.3933 19 19.8134 19H4.18658C3.60667 19 3.0505 18.7743 2.64044 18.3725C2.23037 17.9707 2 17.4258 2 16.8576V10.67C2.00009 10.2659 2.11675 9.87 2.33653 9.52805C2.55632 9.1861 2.87027 8.91198 3.24219 8.73731L11.0709 5.06472C11.1506 5.02731 11.237 5.00565 11.3252 5.00096C11.4134 4.99628 11.5017 5.00868 11.585 5.03743C11.6683 5.06619 11.745 5.11076 11.8108 5.16858C11.8765 5.2264 11.93 5.29634 11.9681 5.37441ZM7.2738 11.5016H4.87608V16.6569H8.23221V13.376H7.27295L7.2738 11.5016ZM14.2248 11.5016H12.0675V16.6569H15.4237L15.4233 13.376H14.2252L14.2248 11.5016Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,12 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_177_2014)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.776 14.304C8.416 14.304 9.696 14.272 11.488 13.536C13.568 12.672 17.664 11.136 20.64 9.536C22.72 8.416 23.616 6.944 23.616 4.96C23.616 2.24 21.408 0 18.656 0H7.136C3.2 0 0 3.2 0 7.136C0 11.072 3.008 14.304 7.776 14.304Z" fill="#39594D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.72803 19.2C9.72803 17.28 10.88 15.52 12.672 14.784L16.288 13.28C19.968 11.776 24 14.464 24 18.432C24 21.504 21.504 24 18.432 24H14.496C11.872 24 9.72803 21.856 9.72803 19.2Z" fill="#D18EE2"/>
<path d="M4.128 15.2319C1.856 15.2319 0 17.0879 0 19.3599V19.9039C0 22.1439 1.856 23.9999 4.128 23.9999C6.4 23.9999 8.256 22.1439 8.256 19.8719V19.3279C8.224 17.0879 6.4 15.2319 4.128 15.2319Z" fill="#FF7759"/>
</g>
<defs>
<clipPath id="clip0_177_2014">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 992 B

View File

@@ -0,0 +1,71 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9473 6.02637L23 12.3937L22.7993 13.7166L11.9576 7.47034L11.9473 6.02637Z" fill="url(#paint0_linear_1003_325075)"/>
<path d="M11.9507 8.45435L22.9999 14.8182L22.7993 16.0823L11.9524 9.90523L11.9507 8.45435Z" fill="url(#paint1_linear_1003_325075)"/>
<path d="M11.9917 10.8616L22.9994 17.1632L22.7988 18.448L12.0125 12.3021L11.9917 10.8616Z" fill="url(#paint2_linear_1003_325075)"/>
<path d="M1 5.95025L1.01211 18.6468L2.25768 18.882L2.21789 5.77905L1 5.95025Z" fill="url(#paint3_linear_1003_325075)"/>
<path d="M3.10889 4.769L3.11062 19.8537L4.37176 19.7949L4.34927 4.58569L3.10889 4.769Z" fill="url(#paint4_linear_1003_325075)"/>
<path d="M5.21729 3.58789V21.0677L6.4767 21.2493L6.48881 3.35962L5.21729 3.58789Z" fill="url(#paint5_linear_1003_325075)"/>
<path d="M1 5.95017L12.0147 12.3019L11.9922 10.8614L2.61924 5.49709C2.37013 5.35529 2.06393 5.35356 1.81481 5.49363L1 5.95017Z" fill="url(#paint6_linear_1003_325075)"/>
<path d="M3.94446 4.30219L3.10889 4.7691L11.9542 9.90514L11.9507 8.45425L4.75062 4.30737C4.5015 4.16384 4.1953 4.16038 3.94446 4.30219Z" fill="url(#paint7_linear_1003_325075)"/>
<path d="M5.21729 3.58798L6.08399 3.10377C6.33484 2.9637 6.64104 2.96543 6.89016 3.10896L11.9468 6.02457L11.9572 7.46854L5.21729 3.58798Z" fill="url(#paint8_linear_1003_325075)"/>
<path d="M12.0204 17.1628L12.017 15.1171L12.0222 14.6951L12.017 14.6986L12.0135 12.3018L1.0127 18.6466L1.84827 19.1291C2.10257 19.276 2.41569 19.2743 2.66827 19.1273L10.8527 14.3493V15.3747L3.11114 19.8536L3.96574 20.3448C4.21658 20.49 4.52624 20.49 4.77882 20.3465L10.8527 16.8758V17.8355L5.2165 21.0693L6.0711 21.5587C6.32194 21.7023 6.6316 21.7023 6.88418 21.5587L10.8544 19.283L12.0239 18.612L12.0204 17.1628Z" fill="url(#paint9_linear_1003_325075)"/>
<path d="M22.9998 17.163L17.5798 20.3311L16.7114 19.8434L22.595 16.4038C22.8458 16.2568 22.9998 15.9888 22.9998 15.6983V14.8163L15.471 19.1448L14.4953 18.5966L22.5812 14.0779C22.8389 13.9344 22.9998 13.6612 22.9998 13.3654V12.3918L12.0215 18.6104L17.1076 21.5243C17.3601 21.6696 17.6698 21.6678 17.9206 21.5226L22.5898 18.8335C22.8424 18.6882 22.9981 18.4185 22.9981 18.1262L22.9998 17.163Z" fill="url(#paint10_linear_1003_325075)"/>
<path d="M21.858 5.56447L17.7701 3.14345C17.5158 2.993 17.2009 2.99127 16.9449 3.13826L11.9453 6.0262L11.9557 7.47017L17.3203 4.35742L18.1628 4.86584L11.9488 8.45414L11.9522 9.90503L19.3945 5.60771L20.2232 6.10748L11.9903 10.8613L12.0128 12.3019L21.8528 6.62108C22.2576 6.38762 22.2611 5.80312 21.858 5.56447Z" fill="url(#paint11_linear_1003_325075)"/>
<defs>
<linearGradient id="paint0_linear_1003_325075" x1="113.894" y1="360.911" x2="1179.98" y2="509.029" gradientUnits="userSpaceOnUse">
<stop stop-color="#148FB4"/>
<stop offset="1" stop-color="#14B4BE"/>
</linearGradient>
<linearGradient id="paint1_linear_1003_325075" x1="71.8713" y1="363.078" x2="1147.45" y2="488.284" gradientUnits="userSpaceOnUse">
<stop stop-color="#148FB4"/>
<stop offset="1" stop-color="#14B4BE"/>
</linearGradient>
<linearGradient id="paint2_linear_1003_325075" x1="83.4027" y1="371.276" x2="1164.81" y2="463.045" gradientUnits="userSpaceOnUse">
<stop stop-color="#148FB4"/>
<stop offset="1" stop-color="#14B4BE"/>
</linearGradient>
<linearGradient id="paint3_linear_1003_325075" x1="63.8806" y1="-12.5896" x2="63.8806" y2="1571.21" gradientUnits="userSpaceOnUse">
<stop stop-color="#3311D4"/>
<stop offset="0.2722" stop-color="#5314E0"/>
<stop offset="0.5453" stop-color="#6C16E9"/>
<stop offset="0.7957" stop-color="#7B18EE"/>
<stop offset="1" stop-color="#8018F0"/>
</linearGradient>
<linearGradient id="paint4_linear_1003_325075" x1="66.2005" y1="111.305" x2="66.2005" y2="1483.1" gradientUnits="userSpaceOnUse">
<stop stop-color="#3311D4"/>
<stop offset="0.2034" stop-color="#4513DB"/>
<stop offset="0.7305" stop-color="#7017EA"/>
<stop offset="1" stop-color="#8018F0"/>
</linearGradient>
<linearGradient id="paint5_linear_1003_325075" x1="68.7154" y1="-253.954" x2="68.7154" y2="2533.3" gradientUnits="userSpaceOnUse">
<stop stop-color="#3311D4"/>
<stop offset="0.6282" stop-color="#8018F0"/>
</linearGradient>
<linearGradient id="paint6_linear_1003_325075" x1="-100.376" y1="178.272" x2="1175.01" y2="951.49" gradientUnits="userSpaceOnUse">
<stop offset="0.1495" stop-color="#645AFF"/>
<stop offset="1" stop-color="#AA64FA"/>
</linearGradient>
<linearGradient id="paint7_linear_1003_325075" x1="-86.4321" y1="141.306" x2="831.625" y2="680.338" gradientUnits="userSpaceOnUse">
<stop offset="0.188" stop-color="#645AFF"/>
<stop offset="1" stop-color="#AA64FA"/>
</linearGradient>
<linearGradient id="paint8_linear_1003_325075" x1="-105.936" y1="97.0607" x2="730.547" y2="568.776" gradientUnits="userSpaceOnUse">
<stop offset="0.2122" stop-color="#645AFF"/>
<stop offset="0.4681" stop-color="#775DFE"/>
<stop offset="0.9857" stop-color="#A964FA"/>
<stop offset="1" stop-color="#AA64FA"/>
</linearGradient>
<linearGradient id="paint9_linear_1003_325075" x1="404.896" y1="791.692" x2="823.67" y2="32.9467" gradientUnits="userSpaceOnUse">
<stop stop-color="#AA64FA"/>
<stop offset="1" stop-color="#645AFF"/>
</linearGradient>
<linearGradient id="paint10_linear_1003_325075" x1="12.1218" y1="474.502" x2="1109.91" y2="474.502" gradientUnits="userSpaceOnUse">
<stop stop-color="#2DF7F7"/>
<stop offset="1" stop-color="#17C8D2"/>
</linearGradient>
<linearGradient id="paint11_linear_1003_325075" x1="12.1027" y1="466.63" x2="1033.29" y2="466.63" gradientUnits="userSpaceOnUse">
<stop stop-color="#17C8D2"/>
<stop offset="1" stop-color="#2DF7F7"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_177_2019)">
<path d="M23.7479 4.482C23.4939 4.358 23.384 4.595 23.236 4.716C23.1849 4.755 23.142 4.806 23.099 4.852C22.727 5.249 22.2929 5.509 21.726 5.478C20.8969 5.432 20.1889 5.692 19.563 6.326C19.43 5.544 18.988 5.078 18.316 4.778C17.964 4.622 17.608 4.467 17.361 4.128C17.1889 3.887 17.142 3.618 17.056 3.354C17.0009 3.194 16.946 3.031 16.763 3.004C16.563 2.973 16.4849 3.14 16.4069 3.28C16.094 3.852 15.9729 4.482 15.9849 5.12C16.0119 6.556 16.618 7.7 17.823 8.513C17.9599 8.606 17.9949 8.7 17.952 8.836C17.8699 9.116 17.772 9.388 17.686 9.669C17.631 9.848 17.549 9.886 17.357 9.809C16.7082 9.53019 16.1189 9.12963 15.6209 8.629C14.7639 7.801 13.9899 6.887 13.0239 6.171C12.8001 6.00562 12.5703 5.84851 12.3349 5.7C11.3499 4.743 12.4649 3.957 12.7229 3.864C12.9929 3.766 12.8159 3.432 11.9439 3.436C11.0719 3.44 10.2739 3.731 9.25695 4.12C9.10582 4.17791 8.95033 4.22372 8.79195 4.257C7.84158 4.07793 6.8696 4.04355 5.90895 4.155C4.02395 4.365 2.51895 5.257 1.41195 6.778C0.0819496 8.606 -0.23105 10.684 0.15195 12.85C0.55495 15.134 1.72095 17.025 3.51195 18.503C5.36995 20.036 7.50895 20.787 9.94995 20.643C11.4319 20.558 13.0829 20.359 14.9439 18.783C15.4139 19.017 15.906 19.11 16.724 19.18C17.354 19.239 17.96 19.15 18.429 19.052C19.164 18.896 19.1129 18.215 18.8479 18.091C16.6929 17.087 17.166 17.496 16.735 17.165C17.831 15.869 19.481 14.523 20.127 10.162C20.177 9.815 20.134 9.597 20.127 9.317C20.123 9.147 20.162 9.08 20.357 9.061C20.898 9.00487 21.4228 8.84351 21.902 8.586C23.298 7.823 23.862 6.571 23.995 5.069C24.015 4.839 23.9909 4.603 23.7479 4.482ZM11.5809 18C9.49195 16.358 8.47895 15.817 8.06095 15.84C7.66895 15.864 7.73995 16.311 7.82595 16.603C7.91595 16.891 8.03295 17.089 8.19695 17.342C8.31095 17.509 8.38895 17.758 8.08395 17.945C7.41095 18.361 6.24195 17.805 6.18695 17.778C4.82595 16.976 3.68695 15.918 2.88595 14.471C2.11195 13.078 1.66195 11.584 1.58795 9.989C1.56795 9.603 1.68095 9.467 2.06495 9.397C2.56906 9.30053 3.08558 9.28735 3.59395 9.358C5.72595 9.67 7.53995 10.623 9.06195 12.132C9.92995 12.992 10.5869 14.019 11.2639 15.023C11.9839 16.089 12.7579 17.105 13.7439 17.937C14.0919 18.229 14.3689 18.451 14.6349 18.614C13.8329 18.704 12.4949 18.724 11.5809 18ZM12.5809 11.56C12.5808 11.5103 12.5927 11.4614 12.6157 11.4173C12.6387 11.3733 12.672 11.3355 12.7129 11.3072C12.7538 11.279 12.8009 11.2611 12.8502 11.2551C12.8995 11.2492 12.9495 11.2553 12.9959 11.273C13.0551 11.2942 13.1062 11.3334 13.142 11.385C13.1779 11.4366 13.1967 11.4982 13.1959 11.561C13.1961 11.6016 13.1881 11.6418 13.1726 11.6793C13.157 11.7168 13.1341 11.7509 13.1053 11.7795C13.0764 11.808 13.0422 11.8306 13.0045 11.8458C12.9669 11.861 12.9266 11.8685 12.8859 11.868C12.8457 11.8681 12.8057 11.8602 12.7685 11.8448C12.7313 11.8293 12.6976 11.8065 12.6693 11.7779C12.641 11.7492 12.6186 11.7151 12.6037 11.6777C12.5887 11.6403 12.5803 11.6003 12.5809 11.56ZM15.6909 13.156C15.4909 13.237 15.2919 13.307 15.1009 13.316C14.8136 13.326 14.5316 13.2363 14.3029 13.062C14.0289 12.832 13.8329 12.704 13.7509 12.304C13.7227 12.1085 13.7281 11.9096 13.7669 11.716C13.8369 11.389 13.7589 11.179 13.5279 10.989C13.3409 10.833 13.1019 10.79 12.8399 10.79C12.7502 10.7848 12.6631 10.758 12.5859 10.712C12.5537 10.6974 12.5249 10.6761 12.5013 10.6497C12.4778 10.6232 12.4601 10.5921 12.4494 10.5583C12.4386 10.5246 12.4351 10.489 12.439 10.4538C12.4429 10.4186 12.4541 10.3846 12.4719 10.354C12.4999 10.3 12.6319 10.168 12.6639 10.144C13.0199 9.942 13.431 10.008 13.8099 10.16C14.162 10.304 14.4279 10.568 14.8109 10.942C15.2019 11.393 15.273 11.518 15.4959 11.856C15.6719 12.121 15.8319 12.393 15.9409 12.704C16.0079 12.899 15.9219 13.058 15.6909 13.156Z" fill="#4D6BFE"/>
</g>
<defs>
<clipPath id="clip0_177_2019">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 140 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 140 KiB

View File

@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21.6601 7.01709C21.9761 6.71199 22.2283 6.34699 22.4017 5.9434C22.5752 5.53981 22.6666 5.10572 22.6705 4.66644C22.6744 4.22717 22.5907 3.79152 22.4244 3.38491C22.2581 2.97831 22.0125 2.6089 21.7019 2.29824C21.3914 1.98758 21.022 1.7419 20.6154 1.57552C20.2089 1.40915 19.7732 1.32542 19.334 1.32923C18.8947 1.33303 18.4606 1.42429 18.0569 1.59767C17.6533 1.77106 17.2883 2.0231 16.9831 2.33909L13.5251 5.79709C13.2091 6.10226 12.9571 6.46731 12.7837 6.87093C12.6103 7.27456 12.519 7.70868 12.5152 8.14795C12.5114 8.58723 12.5952 9.02286 12.7615 9.42943C12.9279 9.836 13.1736 10.2054 13.4842 10.5159C13.7949 10.8265 14.1643 11.0721 14.5709 11.2384C14.9775 11.4047 15.4132 11.4884 15.8524 11.4845C16.2917 11.4806 16.7258 11.3892 17.1294 11.2157C17.533 11.0423 17.898 10.7901 18.2031 10.4741L21.6601 7.01709ZM10.4751 18.2031C10.7871 17.897 11.0354 17.5321 11.2056 17.1295C11.3758 16.7269 11.4645 16.2946 11.4667 15.8575C11.4688 15.4204 11.3842 14.9872 11.2179 14.583C11.0516 14.1787 10.8069 13.8115 10.4978 13.5024C10.1887 13.1933 9.82146 12.9485 9.41722 12.7822C9.01299 12.6159 8.57981 12.5314 8.14271 12.5335C7.70561 12.5356 7.27327 12.6244 6.87066 12.7945C6.46805 12.9647 6.10317 13.213 5.79709 13.5251L2.33909 16.9831C2.0231 17.2883 1.77106 17.6533 1.59767 18.0569C1.42429 18.4606 1.33303 18.8947 1.32923 19.334C1.32542 19.7732 1.40915 20.2089 1.57552 20.6154C1.7419 21.022 1.98758 21.3914 2.29824 21.7019C2.6089 22.0125 2.97831 22.2581 3.38491 22.4244C3.79152 22.5907 4.22717 22.6744 4.66644 22.6705C5.10572 22.6666 5.53981 22.5752 5.9434 22.4017C6.34699 22.2283 6.71199 21.9761 7.01709 21.6601L10.4751 18.2031Z" fill="#7748F9"/>
<path d="M18.2028 13.525C17.8967 13.213 17.5318 12.9647 17.1292 12.7945C16.7266 12.6243 16.2942 12.5356 15.8572 12.5335C15.4201 12.5313 14.9869 12.6159 14.5826 12.7822C14.1784 12.9485 13.8111 13.1932 13.5021 13.5023C13.193 13.8114 12.9482 14.1786 12.7819 14.5829C12.6156 14.9871 12.5311 15.4203 12.5332 15.8574C12.5353 16.2945 12.624 16.7268 12.7942 17.1294C12.9644 17.5321 13.2127 17.8969 13.5248 18.203L16.9828 21.661C17.6052 22.2715 18.4434 22.6116 19.3152 22.6074C20.1869 22.6032 21.0218 22.255 21.6383 21.6385C22.2547 21.0221 22.6029 20.1872 22.6071 19.3154C22.6113 18.4436 22.2712 17.6054 21.6608 16.983L18.2028 13.525ZM7.01677 2.33902C6.7107 2.02697 6.34581 1.77867 5.9432 1.60847C5.5406 1.43828 5.10825 1.34956 4.67115 1.34745C4.23405 1.34534 3.80087 1.42987 3.39664 1.59617C2.99241 1.76246 2.62514 2.00722 2.31606 2.3163C2.00698 2.62538 1.76222 2.99265 1.59592 3.39688C1.42963 3.80112 1.34509 4.2343 1.34721 4.6714C1.34932 5.10849 1.43804 5.54084 1.60823 5.94345C1.77842 6.34605 2.02672 6.71094 2.33877 7.01702L5.79677 10.474C6.42076 11.0764 7.25636 11.4096 8.12362 11.4019C8.99088 11.3942 9.82043 11.0462 10.4336 10.4329C11.0468 9.81955 11.3946 8.98993 11.4022 8.12266C11.4097 7.2554 11.0763 6.41988 10.4738 5.79602L7.01677 2.33902Z" fill="#BFABFB"/>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,13 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1004_325513)">
<path d="M5.30998 15.7561C5.48198 12.0061 7.19298 9.75709 7.85898 9.01709C4.59898 11.0751 2.43398 14.6751 1.50098 17.3251V18.4451C1.50098 21.5131 4.22598 24.0001 7.58998 24.0001C8.3393 24.0011 9.0833 23.8743 9.78998 23.6251C10.143 23.5051 10.49 23.3771 10.829 23.2471C11.742 22.3481 12.479 21.3371 13.072 20.2551C8.19498 22.6861 5.09798 20.3271 5.30898 15.7551L5.30998 15.7561Z" fill="#1E37FC"/>
<path d="M22.5701 10.2829C21.3581 9.38191 18.4611 7.87891 15.1731 7.48291C15.4681 11.2749 15.2661 16.2489 13.0731 20.2559C12.4758 21.3579 11.7198 22.366 10.8291 23.2479C14.5931 21.7999 17.5751 19.7909 19.4251 18.0289C22.2451 15.3459 22.7781 12.8509 22.7861 11.3689C22.7886 10.9966 22.7151 10.6278 22.5701 10.2849V10.2829Z" fill="#37E1BE"/>
<path d="M14.303 1.867C12.955 0.7 11.248 0 9.39 0C7.532 0 5.883 0.677 4.545 1.807C2.791 3.29 1.627 5.557 1.5 8.125V17.326C2.432 14.676 4.597 11.076 7.857 9.019C8.357 8.701 8.882 8.424 9.426 8.19C11.309 7.389 13.304 7.258 15.172 7.484C14.95 4.654 14.454 2.482 14.302 1.867H14.303Z" fill="#A569FF"/>
<path d="M17.3052 4.96094C16.9437 4.59767 16.5837 4.233 16.2252 3.86694C16.0232 3.65394 15.8272 3.44794 15.6392 3.24494L14.3062 1.86694C14.4572 2.48194 14.9542 4.65294 15.1752 7.48394C18.4632 7.87894 21.3602 9.38194 22.5712 10.2839C21.2652 9.00894 19.0962 6.79694 17.3052 4.96094Z" fill="#1E37FC"/>
</g>
<defs>
<clipPath id="clip0_1004_325513">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 1H21V2.64175L13.7455 12L21 21.3582V23H4V1ZM12.6074 10.4857L18.5028 2.64175H6.71105L12.6074 10.4857ZM5.91295 4.60708V11.1796H10.8519L5.91295 4.60708ZM10.8519 12.8204H5.91295V19.3929L10.8519 12.8204ZM6.71105 21.3592L12.6074 13.5153L18.5028 21.3592H6.71105Z" fill="#1F40ED"/>
</svg>

After

Width:  |  Height:  |  Size: 428 B

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.8 5L11.999 11.795L9.195 5H7.397L10.469 12.428C10.5917 12.7301 10.8017 12.9888 11.0722 13.1709C11.3426 13.3531 11.6612 13.4505 11.9873 13.4507C12.3134 13.451 12.6322 13.354 12.9028 13.1721C13.1735 12.9903 13.3839 12.7319 13.507 12.43L16.598 5H14.8ZM15.996 15.352L21.12 10.108L20.421 8.439L14.825 14.178C14.5965 14.4121 14.4422 14.7084 14.3811 15.0298C14.3201 15.3512 14.3552 15.6834 14.482 15.985C14.6065 16.2846 14.8169 16.5406 15.0867 16.7207C15.3565 16.9008 15.6736 16.9969 15.998 16.997L16 17L24 16.98L23.301 15.311L15.998 15.352H15.996ZM2.88 10.104L3.579 8.435L9.175 14.174C9.643 14.653 9.778 15.363 9.518 15.981C9.39342 16.2805 9.18299 16.5364 8.9132 16.7165C8.64342 16.8966 8.32637 16.9928 8.002 16.993L0.002 16.975L0 16.977L0.699 15.308L8.002 15.35L2.88 10.104Z" fill="#5019C5"/>
</svg>

After

Width:  |  Height:  |  Size: 943 B

View File

@@ -0,0 +1,16 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1004_325515)">
<path d="M18 0H6C2.68629 0 0 2.68629 0 6V18C0 21.3137 2.68629 24 6 24H18C21.3137 24 24 21.3137 24 18V6C24 2.68629 21.3137 0 18 0Z" fill="url(#paint0_linear_1004_325515)"/>
<path d="M20 12.0116C15.7043 12.42 12.3692 15.757 11.9995 20C11.652 15.8183 8.20301 12.361 4 12.0181C8.21855 11.6991 11.6656 8.1853 12.006 4C12.2833 8.19653 15.8057 11.7005 20 12.0116Z" fill="white" fill-opacity="0.88"/>
</g>
<defs>
<linearGradient id="paint0_linear_1004_325515" x1="-9" y1="29.5" x2="19.4387" y2="1.43791" gradientUnits="userSpaceOnUse">
<stop offset="0.192878" stop-color="#1C7DFF"/>
<stop offset="0.520213" stop-color="#1C69FF"/>
<stop offset="1" stop-color="#F0DCD6"/>
</linearGradient>
<clipPath id="clip0_1004_325515">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 921 B

View File

@@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1004_325516)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.0792 14.6368C15.2982 15.4516 15.539 16.2847 15.8 17.15C16.0381 17.9395 15.3275 18.25 15.0451 17.5054C14.7426 16.7079 14.4531 15.9137 14.1808 15.1037C12.639 15.8792 11.1015 16.5254 9.35766 17.2524C10.0549 19.8153 10.6985 21.959 11.6971 23.996C11.6971 23.996 11.6972 23.9961 11.6971 23.996C11.7977 23.9985 11.8988 23.9999 12 23.9999C18.6274 23.9999 24 18.6274 24 11.9999C24 9.62004 23.3072 7.4019 22.1122 5.53632C18.9951 5.81715 16.2308 6.27366 13.6911 6.84354C13.7329 7.35114 13.7806 7.84428 13.8333 8.31294C14.0294 10.0562 14.3467 11.7168 14.7682 13.4301C16.2349 12.7708 17.4504 12.1934 18.409 11.7131C19.3292 11.252 20.2166 11.2237 18.7211 12.3956C17.4233 13.2961 16.2386 14.0139 15.0792 14.6368ZM21.6935 4.92502C19.8001 2.33505 16.8937 0.532419 13.5573 0.100071C13.4554 1.71735 13.4871 3.75801 13.6086 5.70262C16.0484 5.3331 18.7033 5.07613 21.6935 4.92502ZM11.9621 0C11.8556 1.75611 11.903 3.99392 12.114 5.9477C10.4249 6.24648 8.8335 6.60378 7.29552 7.02222C7.22916 6.25536 7.19562 5.55453 7.19562 4.94501C7.19562 4.50318 6.83742 4.14501 6.39558 4.14501C5.95378 4.14501 5.59561 4.50318 5.59561 4.94501C5.59561 5.68715 5.65724 6.53874 5.76841 7.46274C5.0014 7.69662 4.24438 7.94652 3.49151 8.21274C3.07496 8.3601 2.85671 8.81718 3.00402 9.2337C3.15134 9.65028 3.60844 9.8685 4.02498 9.7212C4.67586 9.49104 5.33089 9.26322 5.99356 9.03948C6.31332 11.0006 6.80064 13.1656 7.36218 15.2493C7.46016 15.613 7.56372 15.9757 7.67178 16.3357C5.60501 17.048 3.49567 17.6269 1.56677 17.9327C0.569644 16.1829 0 14.158 0 11.9999C0 5.38515 5.35214 0.0204081 11.9621 0ZM2.51491 19.3516C4.47041 21.8709 7.40748 23.5903 10.7522 23.9359C9.95496 22.4729 8.96028 20.2301 8.1243 17.754C6.26424 18.4657 4.3553 18.9616 2.51491 19.3516ZM13.7841 13.868C13.2887 12.2459 12.8677 10.5264 12.5535 8.56614C12.4476 8.1504 12.3551 7.68204 12.2756 7.1781C10.5905 7.5963 8.99952 8.06226 7.46136 8.55582C7.70874 10.4859 8.12688 12.68 8.70708 14.833C8.7972 15.1675 8.88486 15.4948 8.97084 15.8156L8.97144 15.818L8.9838 15.864C9.70998 15.5923 10.4248 15.3073 11.118 15.0155C12.0741 14.6131 12.9631 14.2298 13.7841 13.868Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_1004_325516">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1004_325517)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0099 0.199951C5.36875 0.199951 0 5.60828 0 12.2991C0 17.6475 3.43994 22.1747 8.21205 23.7771C8.80869 23.8975 9.02724 23.5167 9.02724 23.1964C9.02724 22.9159 9.00757 21.9545 9.00757 20.9527C5.6667 21.674 4.97099 19.5104 4.97099 19.5104C4.43409 18.1082 3.63858 17.7478 3.63858 17.7478C2.54511 17.0066 3.71823 17.0066 3.71823 17.0066C4.93117 17.0867 5.56763 18.2485 5.56763 18.2485C6.64118 20.0913 8.37111 19.5706 9.06706 19.25C9.16638 18.4688 9.48473 17.928 9.82275 17.6275C7.15817 17.3471 4.35469 16.3055 4.35469 11.658C4.35469 10.3359 4.8316 9.25423 5.58729 8.41299C5.46807 8.11258 5.0504 6.87039 5.70677 5.20782C5.70677 5.20782 6.72083 4.88725 9.00732 6.44977C9.98625 6.18492 10.9958 6.05019 12.0099 6.04906C13.024 6.04906 14.0577 6.18943 15.0123 6.44977C17.299 4.88725 18.3131 5.20782 18.3131 5.20782C18.9695 6.87039 18.5515 8.11258 18.4323 8.41299C19.2079 9.25423 19.6652 10.3359 19.6652 11.658C19.6652 16.3055 16.8617 17.3269 14.1772 17.6275C14.6148 18.0081 14.9924 18.7291 14.9924 19.871C14.9924 21.4935 14.9727 22.7957 14.9727 23.1962C14.9727 23.5167 15.1915 23.8975 15.7879 23.7773C20.56 22.1745 23.9999 17.6475 23.9999 12.2991C24.0196 5.60828 18.6312 0.199951 12.0099 0.199951Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_1004_325517">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More