Merge branch 'main' into 4-27-app-deploy

This commit is contained in:
Stephen Zhou 2026-05-06 12:39:02 +08:00
commit 8604e72216
No known key found for this signature in database
54 changed files with 1504 additions and 1885 deletions

View File

@ -9,9 +9,9 @@ from typing import TYPE_CHECKING, Any
from pydantic import TypeAdapter
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from configs import dify_config
from core.db.session_factory import session_factory
from core.entities.model_entities import DefaultModelEntity, DefaultModelProviderEntity
from core.entities.provider_configuration import ProviderConfiguration, ProviderConfigurations, ProviderModelBundle
from core.entities.provider_entities import (
@ -445,7 +445,7 @@ class ProviderManager:
@staticmethod
def _get_all_providers(tenant_id: str) -> dict[str, list[Provider]]:
provider_name_to_provider_records_dict = defaultdict(list)
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = select(Provider).where(Provider.tenant_id == tenant_id, Provider.is_valid == True)
providers = session.scalars(stmt)
for provider in providers:
@ -462,7 +462,7 @@ class ProviderManager:
:return:
"""
provider_name_to_provider_model_records_dict = defaultdict(list)
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = select(ProviderModel).where(ProviderModel.tenant_id == tenant_id, ProviderModel.is_valid == True)
provider_models = session.scalars(stmt)
for provider_model in provider_models:
@ -478,7 +478,7 @@ class ProviderManager:
:return:
"""
provider_name_to_preferred_provider_type_records_dict = {}
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = select(TenantPreferredModelProvider).where(TenantPreferredModelProvider.tenant_id == tenant_id)
preferred_provider_types = session.scalars(stmt)
provider_name_to_preferred_provider_type_records_dict = {
@ -496,7 +496,7 @@ class ProviderManager:
:return:
"""
provider_name_to_provider_model_settings_dict = defaultdict(list)
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = select(ProviderModelSetting).where(ProviderModelSetting.tenant_id == tenant_id)
provider_model_settings = session.scalars(stmt)
for provider_model_setting in provider_model_settings:
@ -514,7 +514,7 @@ class ProviderManager:
:return:
"""
provider_name_to_provider_model_credentials_dict = defaultdict(list)
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = select(ProviderModelCredential).where(ProviderModelCredential.tenant_id == tenant_id)
provider_model_credentials = session.scalars(stmt)
for provider_model_credential in provider_model_credentials:
@ -544,7 +544,7 @@ class ProviderManager:
return {}
provider_name_to_provider_load_balancing_model_configs_dict = defaultdict(list)
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = select(LoadBalancingModelConfig).where(LoadBalancingModelConfig.tenant_id == tenant_id)
provider_load_balancing_configs = session.scalars(stmt)
for provider_load_balancing_config in provider_load_balancing_configs:
@ -578,7 +578,7 @@ class ProviderManager:
:param provider_name: provider name
:return:
"""
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = (
select(ProviderCredential)
.where(
@ -608,7 +608,7 @@ class ProviderManager:
:param model_type: model type
:return:
"""
with Session(db.engine, expire_on_commit=False) as session:
with session_factory.create_session() as session:
stmt = (
select(ProviderModelCredential)
.where(

View File

@ -298,7 +298,7 @@ def _build_from_datasource_file(
raise ValueError(f"DatasourceFile {mapping.get('datasource_file_id')} not found")
extension = "." + datasource_file.key.split(".")[-1] if "." in datasource_file.key else ".bin"
detected_file_type = standardize_file_type(extension="." + extension, mime_type=datasource_file.mime_type)
detected_file_type = standardize_file_type(extension=extension, mime_type=datasource_file.mime_type)
file_type = _resolve_file_type(
detected_file_type=detected_file_type,
specified_type=mapping.get("type"),

View File

@ -9,11 +9,11 @@ import sqlalchemy as sa
from sqlalchemy import DateTime, String, func, select, text
from sqlalchemy.orm import Mapped, mapped_column
from core.db.session_factory import session_factory
from graphon.model_runtime.entities.model_entities import ModelType
from libs.uuid_utils import uuidv7
from .base import TypeBase
from .engine import db
from .enums import CredentialSourceType, PaymentStatus, ProviderQuotaType
from .types import EnumText, LongText, StringUUID
@ -82,7 +82,8 @@ class Provider(TypeBase):
@cached_property
def credential(self):
if self.credential_id:
return db.session.scalar(select(ProviderCredential).where(ProviderCredential.id == self.credential_id))
with session_factory.create_session() as session:
return session.scalar(select(ProviderCredential).where(ProviderCredential.id == self.credential_id))
@property
def credential_name(self):
@ -145,9 +146,10 @@ class ProviderModel(TypeBase):
@cached_property
def credential(self):
if self.credential_id:
return db.session.scalar(
select(ProviderModelCredential).where(ProviderModelCredential.id == self.credential_id)
)
with session_factory.create_session() as session:
return session.scalar(
select(ProviderModelCredential).where(ProviderModelCredential.id == self.credential_id)
)
@property
def credential_name(self):

View File

@ -8,6 +8,7 @@ Covers real Redis 7+ sharded pub/sub interactions including:
- Resource cleanup accounting via PUBSUB SHARDNUMSUB
"""
import socket
import threading
import time
import uuid
@ -356,10 +357,17 @@ class TestShardedRedisBroadcastChannelClusterIntegration:
def _get_test_topic_name(cls) -> str:
return f"test_sharded_cluster_topic_{uuid.uuid4()}"
@staticmethod
def _resolve_announced_ip(host: str) -> str:
"""Resolve the container host name to a literal IP accepted by Redis cluster config."""
return socket.getaddrinfo(host, None, type=socket.SOCK_STREAM)[0][4][0]
@staticmethod
def _ensure_single_node_cluster(host: str, port: int) -> None:
"""Bootstrap a single-node cluster using a literal IP for Redis node advertisement."""
client = redis.Redis(host=host, port=port, decode_responses=False)
client.config_set("cluster-announce-ip", host)
announced_ip = TestShardedRedisBroadcastChannelClusterIntegration._resolve_announced_ip(host)
client.config_set("cluster-announce-ip", announced_ip)
client.config_set("cluster-announce-port", port)
slots = client.execute_command("CLUSTER", "SLOTS")
if not slots:

View File

@ -570,8 +570,7 @@ def test_get_all_providers_normalizes_provider_names_with_model_provider_id() ->
session.scalars.return_value = [openai_provider, gemini_provider]
with (
patch("core.provider_manager.db", SimpleNamespace(engine=object())),
patch("core.provider_manager.Session", return_value=_build_session_context(session)),
patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)),
):
result = ProviderManager._get_all_providers("tenant-id")
@ -595,8 +594,7 @@ def test_provider_grouping_helpers_group_records_by_provider_name(method_name: s
session.scalars.return_value = [openai_primary, openai_secondary, anthropic_record]
with (
patch("core.provider_manager.db", SimpleNamespace(engine=object())),
patch("core.provider_manager.Session", return_value=_build_session_context(session)),
patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)),
):
result = getattr(ProviderManager, method_name)("tenant-id")
@ -611,8 +609,7 @@ def test_get_all_preferred_model_providers_returns_mapping_by_provider_name() ->
session.scalars.return_value = [openai_preference, anthropic_preference]
with (
patch("core.provider_manager.db", SimpleNamespace(engine=object())),
patch("core.provider_manager.Session", return_value=_build_session_context(session)),
patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)),
):
result = ProviderManager._get_all_preferred_model_providers("tenant-id")
@ -626,13 +623,13 @@ def test_get_all_provider_load_balancing_configs_returns_empty_when_cached_flag_
with (
patch("core.provider_manager.redis_client.get", return_value=b"False"),
patch("core.provider_manager.FeatureService.get_features") as mock_get_features,
patch("core.provider_manager.Session") as mock_session_cls,
patch("core.provider_manager.session_factory.create_session") as mock_create_session,
):
result = ProviderManager._get_all_provider_load_balancing_configs("tenant-id")
assert result == {}
mock_get_features.assert_not_called()
mock_session_cls.assert_not_called()
mock_create_session.assert_not_called()
def test_get_all_provider_load_balancing_configs_populates_cache_and_groups_configs() -> None:
@ -642,14 +639,13 @@ def test_get_all_provider_load_balancing_configs_populates_cache_and_groups_conf
session.scalars.return_value = [openai_config, anthropic_config]
with (
patch("core.provider_manager.db", SimpleNamespace(engine=object())),
patch("core.provider_manager.redis_client.get", return_value=None),
patch("core.provider_manager.redis_client.setex") as mock_setex,
patch(
"core.provider_manager.FeatureService.get_features",
return_value=SimpleNamespace(model_load_balancing_enabled=True),
),
patch("core.provider_manager.Session", return_value=_build_session_context(session)),
patch("core.provider_manager.session_factory.create_session", return_value=_build_session_context(session)),
):
result = ProviderManager._get_all_provider_load_balancing_configs("tenant-id")

View File

@ -1,8 +1,11 @@
import re
from unittest.mock import MagicMock
import pytest
from factories.file_factory import builders
from factories.file_factory.remote import extract_filename, get_remote_file_info
from graphon.file import FileTransferMethod
class _FakeResponse:
@ -291,3 +294,92 @@ class TestExtractFilename:
"""Test bare path (not full URL) with query string."""
result = extract_filename("/path/to/file.txt?extra=params", None)
assert result == "file.txt"
class TestBuildFromDatasourceFile:
"""Tests for _build_from_datasource_file extension handling."""
@staticmethod
def _patch_session(monkeypatch: pytest.MonkeyPatch, datasource_file):
"""Stub session_factory.create_session() so it returns the given UploadFile-shaped record."""
session = MagicMock()
session.scalar.return_value = datasource_file
ctx = MagicMock()
ctx.__enter__ = MagicMock(return_value=session)
ctx.__exit__ = MagicMock(return_value=False)
monkeypatch.setattr(builders.session_factory, "create_session", lambda: ctx)
def _make_datasource_file(self, *, key: str, mime_type: str = "text/csv"):
f = MagicMock()
f.id = "file-id"
f.key = key
f.name = key.split("/")[-1]
f.mime_type = mime_type
f.size = 123
f.source_url = f"https://example.com/{key}"
return f
def test_extension_passed_without_doubled_dot(self, monkeypatch: pytest.MonkeyPatch):
"""Regression: standardize_file_type must receive the extension exactly once-prefixed.
Previously the call was ``standardize_file_type(extension="." + extension, ...)`` while
``extension`` already had a leading dot, producing ``"..csv"``. The mitigating
``lstrip(".")`` inside ``standardize_file_type`` masked the bug from end users, but the
argument shape itself was wrong and showed up in any caller that didn't strip dots.
"""
captured: dict = {}
def fake_standardize(*, extension: str = "", mime_type: str = ""):
from graphon.file import FileType
captured["extension"] = extension
captured["mime_type"] = mime_type
return FileType.DOCUMENT
monkeypatch.setattr(builders, "standardize_file_type", fake_standardize)
datasource_file = self._make_datasource_file(key="folder/data.csv", mime_type="text/csv")
self._patch_session(monkeypatch, datasource_file)
access_controller = MagicMock()
access_controller.apply_upload_file_filters = lambda stmt: stmt
file = builders._build_from_datasource_file(
mapping={"datasource_file_id": "file-id", "transfer_method": "datasource_file"},
tenant_id="tenant-id",
transfer_method=FileTransferMethod.DATASOURCE_FILE,
access_controller=access_controller,
)
assert captured["extension"] == ".csv", (
f"standardize_file_type received {captured['extension']!r}; expected single-dot '.csv'"
)
assert captured["mime_type"] == "text/csv"
assert file.extension == ".csv"
def test_extension_falls_back_to_bin_when_key_has_no_dot(self, monkeypatch: pytest.MonkeyPatch):
captured: dict = {}
def fake_standardize(*, extension: str = "", mime_type: str = ""):
from graphon.file import FileType
captured["extension"] = extension
return FileType.CUSTOM
monkeypatch.setattr(builders, "standardize_file_type", fake_standardize)
datasource_file = self._make_datasource_file(key="dotless-key", mime_type="application/octet-stream")
self._patch_session(monkeypatch, datasource_file)
access_controller = MagicMock()
access_controller.apply_upload_file_filters = lambda stmt: stmt
file = builders._build_from_datasource_file(
mapping={"datasource_file_id": "file-id", "transfer_method": "datasource_file"},
tenant_id="tenant-id",
transfer_method=FileTransferMethod.DATASOURCE_FILE,
access_controller=access_controller,
)
assert captured["extension"] == ".bin"
assert file.extension == ".bin"

View File

@ -2734,14 +2734,6 @@
"count": 3
}
},
"web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx": {
"no-restricted-imports": {
"count": 1
},
"ts/no-explicit-any": {
"count": 6
}
},
"web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx": {
"unicorn/prefer-number-properties": {
"count": 2
@ -3642,7 +3634,7 @@
},
"web/app/components/workflow/hooks/index.ts": {
"no-barrel-files/no-barrel-files": {
"count": 26
"count": 25
}
},
"web/app/components/workflow/hooks/use-checklist.ts": {

View File

@ -1,6 +1,9 @@
@import 'tailwindcss';
@config '../tailwind.config.ts';
@plugin '../src/plugins/icons.ts';
@source '../src';
@source '../.storybook';
@import '../src/styles/styles.css';

View File

@ -1,6 +1,6 @@
# @langgenius/dify-ui
Shared design tokens, the `cn()` utility, a Tailwind CSS preset, and headless primitive components consumed by `web/`.
Shared design tokens, the `cn()` utility, CSS-first Tailwind styles, and headless primitive components consumed by `web/`.
## Component Authoring Rules
@ -51,7 +51,7 @@ The Figma design system uses `--radius/*` tokens whose scale is **offset by one
### Rules
- **Do not** add custom `borderRadius` values to `tailwind-preset.ts`. We use Tailwind v4 defaults and arbitrary values (`rounded-[Npx]`) for sizes without a standard equivalent.
- **Do not** add custom `borderRadius` theme values. We use Tailwind v4 defaults and arbitrary values (`rounded-[Npx]`) for sizes without a standard equivalent.
- **Do not** use `radius-*` as CSS class names. The old `@utility radius-*` definitions have been removed.
- When the Figma MCP returns `rounded-[var(--radius/sm, 6px)]`, convert it to the standard Tailwind class from the table above (e.g. `rounded-md`).
- For values without a standard Tailwind equivalent (10px, 20px, 28px), use arbitrary values like `rounded-[10px]`.

View File

@ -1,6 +1,6 @@
# @langgenius/dify-ui
Shared UI primitives, design tokens, Tailwind preset, and the `cn()` utility consumed by Dify's `web/` app.
Shared UI primitives, design tokens, CSS-first Tailwind styles, and the `cn()` utility consumed by Dify's `web/` app.
The primitives are thin, opinionated wrappers around [Base UI] headless components, styled with `cva` + `cn` and Dify design tokens.
@ -46,8 +46,22 @@ Importing from `@langgenius/dify-ui` (no subpath) is intentionally not supported
Utilities:
- `./cn``clsx` + `tailwind-merge` wrapper. Use this for conditional class composition.
- `./tailwind-preset` — Tailwind v4 preset with Dify tokens. Apps extend it from their own `tailwind.config.ts`.
- `./styles.css` — the one CSS entry that ships the design tokens, theme variables, and base reset. Import it once from the app root.
- `./styles.css` — the one CSS entry that ships the design tokens, theme variables, and project utilities/components. Import it once from the app root.
## Tailwind CSS v4 integration
This package uses Tailwind CSS v4's CSS-first configuration model. Consumers should import Tailwind from their own root stylesheet, then import this package's CSS entry:
```css
@import 'tailwindcss';
@import '@langgenius/dify-ui/styles.css';
```
If a consumer uses Dify UI source files through the workspace, add an explicit source so Tailwind can detect utility classes:
```css
@source '../packages/dify-ui/src';
```
## Overlay & portal contract

View File

@ -5,10 +5,6 @@
"private": true,
"exports": {
"./styles.css": "./src/styles/styles.css",
"./tailwind-preset": {
"types": "./src/tailwind-preset.ts",
"import": "./src/tailwind-preset.ts"
},
"./cn": {
"types": "./src/cn.ts",
"import": "./src/cn.ts"

View File

@ -19,11 +19,21 @@ export type Placement
| 'left-start'
| 'left-end'
export function parsePlacement(placement: Placement): { side: Side, align: Align } {
const [side, align] = placement.split('-') as [Side, Align | undefined]
const PLACEMENT_PARTS = {
'top': { side: 'top', align: 'center' },
'top-start': { side: 'top', align: 'start' },
'top-end': { side: 'top', align: 'end' },
'right': { side: 'right', align: 'center' },
'right-start': { side: 'right', align: 'start' },
'right-end': { side: 'right', align: 'end' },
'bottom': { side: 'bottom', align: 'center' },
'bottom-start': { side: 'bottom', align: 'start' },
'bottom-end': { side: 'bottom', align: 'end' },
'left': { side: 'left', align: 'center' },
'left-start': { side: 'left', align: 'start' },
'left-end': { side: 'left', align: 'end' },
} satisfies Record<Placement, { side: Side, align: Align }>
return {
side,
align: align ?? 'center',
}
export function parsePlacement(placement: Placement): { side: Side, align: Align } {
return PLACEMENT_PARTS[placement]
}

View File

@ -0,0 +1,10 @@
import { getIconCollections, iconsPlugin } from '@egoist/tailwindcss-icons'
export default iconsPlugin({
collections: getIconCollections(['ri']),
extraProperties: {
width: '1rem',
height: '1rem',
display: 'block',
},
})

View File

@ -13,6 +13,7 @@ export const PopoverTrigger = BasePopover.Trigger
export const PopoverClose = BasePopover.Close
export const PopoverTitle = BasePopover.Title
export const PopoverDescription = BasePopover.Description
export const createPopoverHandle = BasePopover.createHandle
type PopoverContentProps = {
children: ReactNode

View File

@ -1,4 +1,90 @@
/*
* @langgenius/dify-ui Tailwind CSS v4 preset (CSS-first).
*
* This is the single CSS entry point for consumers:
* @import '@langgenius/dify-ui/styles.css';
*
* Consumers must also `@import 'tailwindcss';` (or selected layers) in their
* own root stylesheet so that the engine generates utilities. This file only
* contributes design tokens, runtime CSS variables, and project utilities.
*/
/* ---------- Palette overrides ----------------------------------------- */
/* Override Tailwind v4's oklch defaults with the Dify brand palette so that
* `bg-gray-500`, `text-primary-600`, etc. resolve to the design system. */
@theme {
/* gray */
--color-gray-25: #fcfcfd;
--color-gray-50: #f9fafb;
--color-gray-100: #f2f4f7;
--color-gray-200: #eaecf0;
--color-gray-300: #d0d5dd;
--color-gray-400: #98a2b3;
--color-gray-500: #667085;
--color-gray-600: #344054;
--color-gray-700: #475467;
--color-gray-800: #1d2939;
--color-gray-900: #101828;
/* primary */
--color-primary-25: #f5f8ff;
--color-primary-50: #eff4ff;
--color-primary-100: #d1e0ff;
--color-primary-200: #b2ccff;
--color-primary-300: #84adff;
--color-primary-400: #528bff;
--color-primary-500: #2970ff;
--color-primary-600: #155eef;
--color-primary-700: #004eeb;
--color-primary-800: #0040c1;
--color-primary-900: #00359e;
/* blue / green / yellow / purple — narrow overrides used by legacy markup */
--color-blue-500: #e1effe;
--color-green-50: #f3faf7;
--color-green-100: #def7ec;
--color-green-800: #03543f;
--color-yellow-100: #fdf6b2;
--color-yellow-800: #723b13;
--color-purple-50: #f6f5ff;
--color-purple-200: #dcd7fe;
/* indigo */
--color-indigo-25: #f5f8ff;
--color-indigo-50: #eef4ff;
--color-indigo-100: #e0eaff;
--color-indigo-300: #a4bcfd;
--color-indigo-400: #8098f9;
--color-indigo-600: #444ce7;
--color-indigo-800: #2d31a6;
/* shadows */
--shadow-xs: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
--shadow-sm: 0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10);
--shadow-sm-no-bottom: 0px -1px 2px 0px rgba(16, 24, 40, 0.06), 0px -1px 3px 0px rgba(16, 24, 40, 0.10);
--shadow-md: 0px 2px 4px -2px rgba(16, 24, 40, 0.06), 0px 4px 8px -2px rgba(16, 24, 40, 0.10);
--shadow-lg: 0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08);
--shadow-xl: 0px 8px 8px -4px rgba(16, 24, 40, 0.03), 0px 20px 24px -4px rgba(16, 24, 40, 0.08);
--shadow-2xl: 0px 24px 48px -12px rgba(16, 24, 40, 0.18);
--shadow-3xl: 0px 32px 64px -12px rgba(16, 24, 40, 0.14);
--shadow-status-indicator-green-shadow: 0px 2px 6px 0px var(--color-components-badge-status-light-success-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer);
--shadow-status-indicator-warning-shadow: 0px 2px 6px 0px var(--color-components-badge-status-light-warning-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer);
--shadow-status-indicator-red-shadow: 0px 2px 6px 0px var(--color-components-badge-status-light-error-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer);
--shadow-status-indicator-blue-shadow: 0px 2px 6px 0px var(--color-components-badge-status-light-normal-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer);
--shadow-status-indicator-gray-shadow: 0px 1px 2px 0px var(--color-components-badge-status-light-disabled-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer);
/* font sizes */
--text-2xs: 0.625rem;
}
/* ---------- Semantic design tokens (`@theme inline`) ------------------ */
@import '../themes/theme.css';
/* ---------- Runtime variable values ----------------------------------- */
/* Real values for the semantic tokens above, scoped per `html[data-theme]`. */
@import '../themes/light.css' layer(base);
@import '../themes/dark.css' layer(base);
/* ---------- Project utilities & components ---------------------------- */
@import './utilities.css';
@import './components.css';

View File

@ -1,87 +0,0 @@
import tailwindThemeVarDefine from './themes/tailwind-theme-var-define'
const difyUIPreset = {
theme: {
extend: {
colors: {
gray: {
25: '#fcfcfd',
50: '#f9fafb',
100: '#f2f4f7',
200: '#eaecf0',
300: '#d0d5dd',
400: '#98a2b3',
500: '#667085',
600: '#344054',
700: '#475467',
800: '#1d2939',
900: '#101828',
},
primary: {
25: '#f5f8ff',
50: '#eff4ff',
100: '#d1e0ff',
200: '#b2ccff',
300: '#84adff',
400: '#528bff',
500: '#2970ff',
600: '#155eef',
700: '#004eeb',
800: '#0040c1',
900: '#00359e',
},
blue: {
500: '#E1EFFE',
},
green: {
50: '#F3FAF7',
100: '#DEF7EC',
800: '#03543F',
},
yellow: {
100: '#FDF6B2',
800: '#723B13',
},
purple: {
50: '#F6F5FF',
200: '#DCD7FE',
},
indigo: {
25: '#F5F8FF',
50: '#EEF4FF',
100: '#E0EAFF',
300: '#A4BCFD',
400: '#8098F9',
600: '#444CE7',
800: '#2D31A6',
},
...tailwindThemeVarDefine,
},
boxShadow: {
'xs': '0px 1px 2px 0px rgba(16, 24, 40, 0.05)',
'sm': '0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10)',
'sm-no-bottom': '0px -1px 2px 0px rgba(16, 24, 40, 0.06), 0px -1px 3px 0px rgba(16, 24, 40, 0.10)',
'md': '0px 2px 4px -2px rgba(16, 24, 40, 0.06), 0px 4px 8px -2px rgba(16, 24, 40, 0.10)',
'lg': '0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08)',
'xl': '0px 8px 8px -4px rgba(16, 24, 40, 0.03), 0px 20px 24px -4px rgba(16, 24, 40, 0.08)',
'2xl': '0px 24px 48px -12px rgba(16, 24, 40, 0.18)',
'3xl': '0px 32px 64px -12px rgba(16, 24, 40, 0.14)',
'status-indicator-green-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-success-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-warning-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-warning-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-red-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-error-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-blue-shadow': '0px 2px 6px 0px var(--color-components-badge-status-light-normal-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
'status-indicator-gray-shadow': '0px 1px 2px 0px var(--color-components-badge-status-light-disabled-halo), 0px 0px 0px 1px var(--color-components-badge-status-light-border-outer)',
},
opacity: {
2: '0.02',
8: '0.08',
},
fontSize: {
'2xs': '0.625rem',
},
},
},
plugins: [],
}
export default difyUIPreset

View File

@ -6,18 +6,6 @@ html[data-theme="dark"] {
--color-components-input-bg-active: rgb(255 255 255 / 0.05);
--color-components-input-border-active: #747481;
--color-components-input-border-destructive: #f97066;
/* Sticky header / Monaco editor sticky scroll colors (dark mode) */
/* Use solid panel background to ensure visibility when elements become sticky */
--color-components-sticky-header-bg: var(--color-components-panel-bg);
--color-components-sticky-header-bg-hover: var(--color-components-panel-on-panel-item-bg-hover);
--color-components-sticky-header-border: var(--color-components-panel-border);
/* Override Monaco/VSCode CSS variables for sticky scroll so the sticky header is opaque */
--vscode-editorStickyScroll-background: var(--color-components-sticky-header-bg);
--vscode-editorStickyScrollHover-background: var(--color-components-sticky-header-bg-hover);
--vscode-editorStickyScroll-border: var(--color-components-sticky-header-border);
--vscode-editorStickyScroll-shadow: rgba(0, 0, 0, 0.6);
--color-components-input-text-filled: #f4f4f5;
--color-components-input-bg-destructive: rgb(255 255 255 / 0.01);
--color-components-input-bg-disabled: rgb(255 255 255 / 0.03);
@ -101,17 +89,6 @@ html[data-theme="dark"] {
--color-components-button-indigo-bg-hover: #6172f3;
--color-components-button-indigo-bg-disabled: rgb(255 255 255 / 0.03);
--color-components-button-debug-text: rgb(255 255 255 / 0.95);
--color-components-button-debug-text-disabled: rgb(255 255 255 / 0.2);
--color-components-button-debug-bg: #ff4405;
--color-components-button-debug-bg-hover: #ff692e;
--color-components-button-debug-bg-disabled: rgb(255 68 5 / 0.08);
--color-components-button-debug-border: rgb(255 255 255 / 0.12);
--color-components-button-debug-border-hover: rgb(255 255 255 / 0.2);
--color-components-button-debug-border-disabled: rgb(255 255 255 / 0.08);
--color-components-button-button-seam: rgb(0 0 0 / 0.15);
--color-components-checkbox-icon: rgb(255 255 255 / 0.95);
--color-components-checkbox-icon-disabled: rgb(255 255 255 / 0.2);
--color-components-checkbox-bg: #296dff;
@ -172,7 +149,6 @@ html[data-theme="dark"] {
--color-components-panel-on-panel-item-bg-destructive-hover-transparent: rgb(255 251 250 / 0);
--color-components-panel-bg-transparent: rgb(34 34 37 / 0);
--color-components-panel-bg-blur-burn: rgb(31 31 35 / 0.9);
--color-components-main-nav-nav-button-text: rgb(200 206 218 / 0.6);
--color-components-main-nav-nav-button-text-active: #f4f4f5;
@ -183,26 +159,6 @@ html[data-theme="dark"] {
--color-components-main-nav-nav-user-border: rgb(255 255 255 / 0.05);
--color-components-main-nav-text: #a8a8b3;
--color-components-main-nav-text-active: #ffffff;
--color-components-main-nav-glass-edge-highlight-first: rgb(196 207 255 / 0.15);
--color-components-main-nav-glass-edge-highlight-middle: rgb(72 108 255 / 0);
--color-components-main-nav-glass-edge-highlight-end: rgb(196 207 255 / 0.05);
--color-components-main-nav-glass-edge-reflection-first: rgb(92 124 255 / 0);
--color-components-main-nav-glass-edge-reflection-middle: rgb(210 219 255 / 0.8);
--color-components-main-nav-glass-edge-reflection-end: rgb(92 124 255 / 0);
--color-components-main-nav-glass-surface-first: rgb(196 207 255 / 0.08);
--color-components-main-nav-glass-surface-middle-1: rgb(210 219 255 / 0.12);
--color-components-main-nav-glass-surface-middle-2: rgb(210 219 255 / 0.1);
--color-components-main-nav-glass-surface-end: rgb(196 207 255 / 0.08);
--color-components-main-nav-glass-inner-glow: rgb(210 219 255 / 0.05);
--color-components-main-nav-glass-shadow-reflection: rgb(210 219 255 / 0.04);
--color-components-main-nav-glass-shadow-reflection-glow: rgb(255 255 255 / 0.02);
--color-components-main-nav-glass-text-glow: rgb(245 246 255 / 0.27);
--color-components-slider-knob: #f4f4f5;
--color-components-slider-knob-hover: #fefefe;
--color-components-slider-knob-disabled: rgb(255 255 255 / 0.2);
@ -401,8 +357,6 @@ html[data-theme="dark"] {
--color-components-icon-bg-orange-solid: #f79009;
--color-components-icon-bg-orange-soft: rgb(247 144 9 / 0.2);
--color-components-marketplace-header-bg: rgb(31 31 35 / 0.9);
--color-text-primary: #fbfbfc;
--color-text-secondary: #d9d9de;
--color-text-tertiary: rgb(200 206 218 / 0.6);
@ -464,7 +418,6 @@ html[data-theme="dark"] {
--color-background-overlay-backdrop: rgb(24 24 27 / 0.95);
--color-background-body-transparent: rgb(29 29 32 / 0);
--color-background-section-burn-inverted: #27272b;
--color-background-default-hover-alpha-0: rgb(39 39 43 / 0);
--color-shadow-shadow-1: rgb(0 0 0 / 0.05);
--color-shadow-shadow-3: rgb(0 0 0 / 0.1);
@ -548,18 +501,6 @@ html[data-theme="dark"] {
--color-workflow-workflow-progress-bg-1: rgb(24 24 27 / 0.25);
--color-workflow-workflow-progress-bg-2: rgb(24 24 27 / 0.04);
--color-workflow-debug-run-status-bg: rgb(230 46 5 / 0.4);
--color-workflow-debug-breakpoint: #ff692e;
--color-workflow-debug-text: #ff9c66;
--color-workflow-debug-text-disabled: rgb(255 68 5 / 0.2);
--color-workflow-debug-run-status-bg-alt: rgb(255 46 0 / 0.5);
--color-workflow-test-run-run-status-bg: rgb(21 90 239 / 0.5);
--color-workflow-test-run-text: #d1e0ff;
--color-workflow-test-run-run-status-bg-alt: rgb(45 90 190 / 0.9);
--color-workflow-test-run-paused-bg: rgb(247 144 9 / 0.3);
--color-workflow-test-run-paused-text: #fdb022;
--color-divider-subtle: rgb(200 206 218 / 0.08);
--color-divider-regular: rgb(200 206 218 / 0.14);
--color-divider-deep: rgb(200 206 218 / 0.2);
@ -604,7 +545,6 @@ html[data-theme="dark"] {
--color-effects-highlight-lightmode-off: rgb(200 206 218 / 0.08);
--color-effects-image-frame: #ffffff;
--color-effects-icon-border: rgb(255 255 255 / 0.15);
--color-effects-highlight-subtle: rgb(200 206 218 / 0.04);
--color-util-colors-orange-dark-orange-dark-50: #57130a;
--color-util-colors-orange-dark-orange-dark-100: #771a0d;
@ -821,7 +761,5 @@ html[data-theme="dark"] {
--color-dify-logo-blue: #e8e8e8;
--color-dify-logo-black: #e8e8e8;
--color-dify-logo-outline-1: #ffffff;
--color-dify-logo-outline-2: #e8e8e8;
}
}

View File

@ -89,17 +89,6 @@ html[data-theme="light"] {
--color-components-button-indigo-bg-hover: #3538cd;
--color-components-button-indigo-bg-disabled: rgb(97 114 243 / 0.14);
--color-components-button-debug-text: #ffffff;
--color-components-button-debug-text-disabled: rgb(255 255 255 / 0.6);
--color-components-button-debug-bg: #ff4405;
--color-components-button-debug-bg-hover: #e62e05;
--color-components-button-debug-bg-disabled: rgb(255 68 5 / 0.2);
--color-components-button-debug-border: rgb(16 24 40 / 0.04);
--color-components-button-debug-border-hover: rgb(16 24 40 / 0.08);
--color-components-button-debug-border-disabled: rgb(255 255 255 / 0);
--color-components-button-button-seam: rgb(0 0 0 / 0.03);
--color-components-checkbox-icon: #ffffff;
--color-components-checkbox-icon-disabled: rgb(255 255 255 / 0.5);
--color-components-checkbox-bg: #155aef;
@ -160,7 +149,6 @@ html[data-theme="light"] {
--color-components-panel-on-panel-item-bg-destructive-hover-transparent: rgb(254 243 242 / 0);
--color-components-panel-bg-transparent: rgb(255 255 255 / 0);
--color-components-panel-bg-blur-burn: rgb(255 255 255 / 0.9);
--color-components-main-nav-nav-button-text: #495464;
--color-components-main-nav-nav-button-text-active: #155aef;
@ -171,26 +159,6 @@ html[data-theme="light"] {
--color-components-main-nav-nav-user-border: #ffffff;
--color-components-main-nav-text: #495464;
--color-components-main-nav-text-active: #0033ff;
--color-components-main-nav-glass-edge-highlight-first: rgb(255 255 255 / 0.98);
--color-components-main-nav-glass-edge-highlight-middle: rgb(255 255 255 / 0);
--color-components-main-nav-glass-edge-highlight-end: rgb(255 255 255 / 0.42);
--color-components-main-nav-glass-edge-reflection-first: rgb(0 51 255 / 0);
--color-components-main-nav-glass-edge-reflection-middle: rgb(0 51 255 / 0.6);
--color-components-main-nav-glass-edge-reflection-end: rgb(0 51 255 / 0);
--color-components-main-nav-glass-surface-first: rgb(0 51 255 / 0.08);
--color-components-main-nav-glass-surface-middle-1: rgb(0 51 255 / 0.12);
--color-components-main-nav-glass-surface-middle-2: rgb(0 51 255 / 0.1);
--color-components-main-nav-glass-surface-end: rgb(0 51 255 / 0.08);
--color-components-main-nav-glass-inner-glow: rgb(255 255 255 / 0.3);
--color-components-main-nav-glass-shadow-reflection: rgb(0 51 255 / 0.06);
--color-components-main-nav-glass-shadow-reflection-glow: rgb(255 255 255 / 0);
--color-components-main-nav-glass-text-glow: rgb(49 70 255 / 0.18);
--color-components-slider-knob: #ffffff;
--color-components-slider-knob-hover: #ffffff;
--color-components-slider-knob-disabled: rgb(255 255 255 / 0.95);
@ -389,8 +357,6 @@ html[data-theme="light"] {
--color-components-icon-bg-orange-solid: #f79009;
--color-components-icon-bg-orange-soft: #fffaeb;
--color-components-marketplace-header-bg: rgb(255 255 255 / 0.98);
--color-text-primary: #101828;
--color-text-secondary: #354052;
--color-text-tertiary: #676f83;
@ -452,7 +418,6 @@ html[data-theme="light"] {
--color-background-overlay-backdrop: rgb(242 244 247 / 0.95);
--color-background-body-transparent: rgb(242 244 247 / 0);
--color-background-section-burn-inverted: #f2f4f7;
--color-background-default-hover-alpha-0: rgb(249 250 251 / 0);
--color-shadow-shadow-1: rgb(9 9 11 / 0.03);
--color-shadow-shadow-3: rgb(9 9 11 / 0.05);
@ -536,18 +501,6 @@ html[data-theme="light"] {
--color-workflow-workflow-progress-bg-1: rgb(200 206 218 / 0.2);
--color-workflow-workflow-progress-bg-2: rgb(200 206 218 / 0.04);
--color-workflow-debug-run-status-bg: rgb(255 68 5 / 0.08);
--color-workflow-debug-breakpoint: #e62e05;
--color-workflow-debug-text: #e62e05;
--color-workflow-debug-text-disabled: rgb(255 68 5 / 0.2);
--color-workflow-debug-run-status-bg-alt: rgb(255 68 5 / 0.14);
--color-workflow-test-run-run-status-bg: rgb(21 90 239 / 0.08);
--color-workflow-test-run-text: #004aeb;
--color-workflow-test-run-run-status-bg-alt: rgb(21 90 239 / 0.14);
--color-workflow-test-run-paused-bg: rgb(247 144 9 / 0.14);
--color-workflow-test-run-paused-text: #dc6803;
--color-divider-subtle: rgb(16 24 40 / 0.04);
--color-divider-regular: rgb(16 24 40 / 0.08);
--color-divider-deep: rgb(16 24 40 / 0.14);
@ -592,7 +545,6 @@ html[data-theme="light"] {
--color-effects-highlight-lightmode-off: rgb(255 255 255 / 0);
--color-effects-image-frame: #ffffff;
--color-effects-icon-border: rgb(16 24 40 / 0.08);
--color-effects-highlight-subtle: rgb(255 255 255 / 0.5);
--color-util-colors-orange-dark-orange-dark-50: #fff4ed;
--color-util-colors-orange-dark-orange-dark-100: #ffe6d5;
@ -809,7 +761,5 @@ html[data-theme="light"] {
--color-dify-logo-blue: #0033ff;
--color-dify-logo-black: #000000;
--color-dify-logo-outline-1: rgb(0 0 0 / 0);
--color-dify-logo-outline-2: rgb(0 0 0 / 0);
}
}

View File

@ -1,816 +0,0 @@
/* Attention: Generate by code. Don't update by hand!!! */
const vars = {
'components-input-bg-normal': 'var(--color-components-input-bg-normal)',
'components-input-text-placeholder': 'var(--color-components-input-text-placeholder)',
'components-input-bg-hover': 'var(--color-components-input-bg-hover)',
'components-input-bg-active': 'var(--color-components-input-bg-active)',
'components-input-border-active': 'var(--color-components-input-border-active)',
'components-input-border-destructive': 'var(--color-components-input-border-destructive)',
'components-input-text-filled': 'var(--color-components-input-text-filled)',
'components-input-bg-destructive': 'var(--color-components-input-bg-destructive)',
'components-input-bg-disabled': 'var(--color-components-input-bg-disabled)',
'components-input-text-disabled': 'var(--color-components-input-text-disabled)',
'components-input-text-filled-disabled': 'var(--color-components-input-text-filled-disabled)',
'components-input-border-hover': 'var(--color-components-input-border-hover)',
'components-input-border-active-prompt-1': 'var(--color-components-input-border-active-prompt-1)',
'components-input-border-active-prompt-2': 'var(--color-components-input-border-active-prompt-2)',
'components-kbd-bg-gray': 'var(--color-components-kbd-bg-gray)',
'components-kbd-bg-white': 'var(--color-components-kbd-bg-white)',
'components-tooltip-bg': 'var(--color-components-tooltip-bg)',
'components-button-primary-text': 'var(--color-components-button-primary-text)',
'components-button-primary-bg': 'var(--color-components-button-primary-bg)',
'components-button-primary-border': 'var(--color-components-button-primary-border)',
'components-button-primary-bg-hover': 'var(--color-components-button-primary-bg-hover)',
'components-button-primary-border-hover': 'var(--color-components-button-primary-border-hover)',
'components-button-primary-bg-disabled': 'var(--color-components-button-primary-bg-disabled)',
'components-button-primary-border-disabled': 'var(--color-components-button-primary-border-disabled)',
'components-button-primary-text-disabled': 'var(--color-components-button-primary-text-disabled)',
'components-button-secondary-text': 'var(--color-components-button-secondary-text)',
'components-button-secondary-text-disabled': 'var(--color-components-button-secondary-text-disabled)',
'components-button-secondary-bg': 'var(--color-components-button-secondary-bg)',
'components-button-secondary-bg-hover': 'var(--color-components-button-secondary-bg-hover)',
'components-button-secondary-bg-disabled': 'var(--color-components-button-secondary-bg-disabled)',
'components-button-secondary-border': 'var(--color-components-button-secondary-border)',
'components-button-secondary-border-hover': 'var(--color-components-button-secondary-border-hover)',
'components-button-secondary-border-disabled': 'var(--color-components-button-secondary-border-disabled)',
'components-button-tertiary-text': 'var(--color-components-button-tertiary-text)',
'components-button-tertiary-text-disabled': 'var(--color-components-button-tertiary-text-disabled)',
'components-button-tertiary-bg': 'var(--color-components-button-tertiary-bg)',
'components-button-tertiary-bg-hover': 'var(--color-components-button-tertiary-bg-hover)',
'components-button-tertiary-bg-disabled': 'var(--color-components-button-tertiary-bg-disabled)',
'components-button-ghost-text': 'var(--color-components-button-ghost-text)',
'components-button-ghost-text-disabled': 'var(--color-components-button-ghost-text-disabled)',
'components-button-ghost-bg-hover': 'var(--color-components-button-ghost-bg-hover)',
'components-button-destructive-primary-text': 'var(--color-components-button-destructive-primary-text)',
'components-button-destructive-primary-text-disabled': 'var(--color-components-button-destructive-primary-text-disabled)',
'components-button-destructive-primary-bg': 'var(--color-components-button-destructive-primary-bg)',
'components-button-destructive-primary-bg-hover': 'var(--color-components-button-destructive-primary-bg-hover)',
'components-button-destructive-primary-bg-disabled': 'var(--color-components-button-destructive-primary-bg-disabled)',
'components-button-destructive-primary-border': 'var(--color-components-button-destructive-primary-border)',
'components-button-destructive-primary-border-hover': 'var(--color-components-button-destructive-primary-border-hover)',
'components-button-destructive-primary-border-disabled': 'var(--color-components-button-destructive-primary-border-disabled)',
'components-button-destructive-secondary-text': 'var(--color-components-button-destructive-secondary-text)',
'components-button-destructive-secondary-text-disabled': 'var(--color-components-button-destructive-secondary-text-disabled)',
'components-button-destructive-secondary-bg': 'var(--color-components-button-destructive-secondary-bg)',
'components-button-destructive-secondary-bg-hover': 'var(--color-components-button-destructive-secondary-bg-hover)',
'components-button-destructive-secondary-bg-disabled': 'var(--color-components-button-destructive-secondary-bg-disabled)',
'components-button-destructive-secondary-border': 'var(--color-components-button-destructive-secondary-border)',
'components-button-destructive-secondary-border-hover': 'var(--color-components-button-destructive-secondary-border-hover)',
'components-button-destructive-secondary-border-disabled': 'var(--color-components-button-destructive-secondary-border-disabled)',
'components-button-destructive-tertiary-text': 'var(--color-components-button-destructive-tertiary-text)',
'components-button-destructive-tertiary-text-disabled': 'var(--color-components-button-destructive-tertiary-text-disabled)',
'components-button-destructive-tertiary-bg': 'var(--color-components-button-destructive-tertiary-bg)',
'components-button-destructive-tertiary-bg-hover': 'var(--color-components-button-destructive-tertiary-bg-hover)',
'components-button-destructive-tertiary-bg-disabled': 'var(--color-components-button-destructive-tertiary-bg-disabled)',
'components-button-destructive-ghost-text': 'var(--color-components-button-destructive-ghost-text)',
'components-button-destructive-ghost-text-disabled': 'var(--color-components-button-destructive-ghost-text-disabled)',
'components-button-destructive-ghost-bg-hover': 'var(--color-components-button-destructive-ghost-bg-hover)',
'components-button-secondary-accent-text': 'var(--color-components-button-secondary-accent-text)',
'components-button-secondary-accent-text-disabled': 'var(--color-components-button-secondary-accent-text-disabled)',
'components-button-secondary-accent-bg': 'var(--color-components-button-secondary-accent-bg)',
'components-button-secondary-accent-bg-hover': 'var(--color-components-button-secondary-accent-bg-hover)',
'components-button-secondary-accent-bg-disabled': 'var(--color-components-button-secondary-accent-bg-disabled)',
'components-button-secondary-accent-border': 'var(--color-components-button-secondary-accent-border)',
'components-button-secondary-accent-border-hover': 'var(--color-components-button-secondary-accent-border-hover)',
'components-button-secondary-accent-border-disabled': 'var(--color-components-button-secondary-accent-border-disabled)',
'components-button-indigo-bg': 'var(--color-components-button-indigo-bg)',
'components-button-indigo-bg-hover': 'var(--color-components-button-indigo-bg-hover)',
'components-button-indigo-bg-disabled': 'var(--color-components-button-indigo-bg-disabled)',
'components-button-debug-text': 'var(--color-components-button-debug-text)',
'components-button-debug-text-disabled': 'var(--color-components-button-debug-text-disabled)',
'components-button-debug-bg': 'var(--color-components-button-debug-bg)',
'components-button-debug-bg-hover': 'var(--color-components-button-debug-bg-hover)',
'components-button-debug-bg-disabled': 'var(--color-components-button-debug-bg-disabled)',
'components-button-debug-border': 'var(--color-components-button-debug-border)',
'components-button-debug-border-hover': 'var(--color-components-button-debug-border-hover)',
'components-button-debug-border-disabled': 'var(--color-components-button-debug-border-disabled)',
'components-button-button-seam': 'var(--color-components-button-button-seam)',
'components-checkbox-icon': 'var(--color-components-checkbox-icon)',
'components-checkbox-icon-disabled': 'var(--color-components-checkbox-icon-disabled)',
'components-checkbox-bg': 'var(--color-components-checkbox-bg)',
'components-checkbox-bg-hover': 'var(--color-components-checkbox-bg-hover)',
'components-checkbox-bg-disabled': 'var(--color-components-checkbox-bg-disabled)',
'components-checkbox-border': 'var(--color-components-checkbox-border)',
'components-checkbox-border-hover': 'var(--color-components-checkbox-border-hover)',
'components-checkbox-border-disabled': 'var(--color-components-checkbox-border-disabled)',
'components-checkbox-bg-unchecked': 'var(--color-components-checkbox-bg-unchecked)',
'components-checkbox-bg-unchecked-hover': 'var(--color-components-checkbox-bg-unchecked-hover)',
'components-checkbox-bg-disabled-checked': 'var(--color-components-checkbox-bg-disabled-checked)',
'components-radio-border-checked': 'var(--color-components-radio-border-checked)',
'components-radio-border-checked-hover': 'var(--color-components-radio-border-checked-hover)',
'components-radio-border-checked-disabled': 'var(--color-components-radio-border-checked-disabled)',
'components-radio-bg-disabled': 'var(--color-components-radio-bg-disabled)',
'components-radio-border': 'var(--color-components-radio-border)',
'components-radio-border-hover': 'var(--color-components-radio-border-hover)',
'components-radio-border-disabled': 'var(--color-components-radio-border-disabled)',
'components-radio-bg': 'var(--color-components-radio-bg)',
'components-radio-bg-hover': 'var(--color-components-radio-bg-hover)',
'components-toggle-knob': 'var(--color-components-toggle-knob)',
'components-toggle-knob-disabled': 'var(--color-components-toggle-knob-disabled)',
'components-toggle-bg': 'var(--color-components-toggle-bg)',
'components-toggle-bg-hover': 'var(--color-components-toggle-bg-hover)',
'components-toggle-bg-disabled': 'var(--color-components-toggle-bg-disabled)',
'components-toggle-bg-unchecked': 'var(--color-components-toggle-bg-unchecked)',
'components-toggle-bg-unchecked-hover': 'var(--color-components-toggle-bg-unchecked-hover)',
'components-toggle-bg-unchecked-disabled': 'var(--color-components-toggle-bg-unchecked-disabled)',
'components-toggle-knob-hover': 'var(--color-components-toggle-knob-hover)',
'components-card-bg': 'var(--color-components-card-bg)',
'components-card-border': 'var(--color-components-card-border)',
'components-card-bg-alt': 'var(--color-components-card-bg-alt)',
'components-card-bg-transparent': 'var(--color-components-card-bg-transparent)',
'components-card-bg-alt-transparent': 'var(--color-components-card-bg-alt-transparent)',
'components-menu-item-text': 'var(--color-components-menu-item-text)',
'components-menu-item-text-active': 'var(--color-components-menu-item-text-active)',
'components-menu-item-text-hover': 'var(--color-components-menu-item-text-hover)',
'components-menu-item-text-active-accent': 'var(--color-components-menu-item-text-active-accent)',
'components-menu-item-bg-active': 'var(--color-components-menu-item-bg-active)',
'components-menu-item-bg-hover': 'var(--color-components-menu-item-bg-hover)',
'components-panel-bg': 'var(--color-components-panel-bg)',
'components-panel-bg-blur': 'var(--color-components-panel-bg-blur)',
'components-panel-border': 'var(--color-components-panel-border)',
'components-panel-border-subtle': 'var(--color-components-panel-border-subtle)',
'components-panel-gradient-2': 'var(--color-components-panel-gradient-2)',
'components-panel-gradient-1': 'var(--color-components-panel-gradient-1)',
'components-panel-bg-alt': 'var(--color-components-panel-bg-alt)',
'components-panel-on-panel-item-bg': 'var(--color-components-panel-on-panel-item-bg)',
'components-panel-on-panel-item-bg-hover': 'var(--color-components-panel-on-panel-item-bg-hover)',
'components-panel-on-panel-item-bg-alt': 'var(--color-components-panel-on-panel-item-bg-alt)',
'components-panel-on-panel-item-bg-transparent': 'var(--color-components-panel-on-panel-item-bg-transparent)',
'components-panel-on-panel-item-bg-hover-transparent': 'var(--color-components-panel-on-panel-item-bg-hover-transparent)',
'components-panel-on-panel-item-bg-destructive-hover-transparent': 'var(--color-components-panel-on-panel-item-bg-destructive-hover-transparent)',
'components-panel-bg-transparent': 'var(--color-components-panel-bg-transparent)',
'components-panel-bg-blur-burn': 'var(--color-components-panel-bg-blur-burn)',
'components-main-nav-nav-button-text': 'var(--color-components-main-nav-nav-button-text)',
'components-main-nav-nav-button-text-active': 'var(--color-components-main-nav-nav-button-text-active)',
'components-main-nav-nav-button-bg': 'var(--color-components-main-nav-nav-button-bg)',
'components-main-nav-nav-button-bg-active': 'var(--color-components-main-nav-nav-button-bg-active)',
'components-main-nav-nav-button-border': 'var(--color-components-main-nav-nav-button-border)',
'components-main-nav-nav-button-bg-hover': 'var(--color-components-main-nav-nav-button-bg-hover)',
'components-main-nav-nav-user-border': 'var(--color-components-main-nav-nav-user-border)',
'components-main-nav-text': 'var(--color-components-main-nav-text)',
'components-main-nav-text-active': 'var(--color-components-main-nav-text-active)',
'components-main-nav-glass-edge-highlight-first': 'var(--color-components-main-nav-glass-edge-highlight-first)',
'components-main-nav-glass-edge-highlight-middle': 'var(--color-components-main-nav-glass-edge-highlight-middle)',
'components-main-nav-glass-edge-highlight-end': 'var(--color-components-main-nav-glass-edge-highlight-end)',
'components-main-nav-glass-edge-reflection-first': 'var(--color-components-main-nav-glass-edge-reflection-first)',
'components-main-nav-glass-edge-reflection-middle': 'var(--color-components-main-nav-glass-edge-reflection-middle)',
'components-main-nav-glass-edge-reflection-end': 'var(--color-components-main-nav-glass-edge-reflection-end)',
'components-main-nav-glass-surface-first': 'var(--color-components-main-nav-glass-surface-first)',
'components-main-nav-glass-surface-middle-1': 'var(--color-components-main-nav-glass-surface-middle-1)',
'components-main-nav-glass-surface-middle-2': 'var(--color-components-main-nav-glass-surface-middle-2)',
'components-main-nav-glass-surface-end': 'var(--color-components-main-nav-glass-surface-end)',
'components-main-nav-glass-inner-glow': 'var(--color-components-main-nav-glass-inner-glow)',
'components-main-nav-glass-shadow-reflection': 'var(--color-components-main-nav-glass-shadow-reflection)',
'components-main-nav-glass-shadow-reflection-glow': 'var(--color-components-main-nav-glass-shadow-reflection-glow)',
'components-main-nav-glass-text-glow': 'var(--color-components-main-nav-glass-text-glow)',
'components-slider-knob': 'var(--color-components-slider-knob)',
'components-slider-knob-hover': 'var(--color-components-slider-knob-hover)',
'components-slider-knob-disabled': 'var(--color-components-slider-knob-disabled)',
'components-slider-range': 'var(--color-components-slider-range)',
'components-slider-track': 'var(--color-components-slider-track)',
'components-slider-knob-border-hover': 'var(--color-components-slider-knob-border-hover)',
'components-slider-knob-border': 'var(--color-components-slider-knob-border)',
'components-segmented-control-item-active-bg': 'var(--color-components-segmented-control-item-active-bg)',
'components-segmented-control-item-active-border': 'var(--color-components-segmented-control-item-active-border)',
'components-segmented-control-bg-normal': 'var(--color-components-segmented-control-bg-normal)',
'components-segmented-control-item-active-accent-bg': 'var(--color-components-segmented-control-item-active-accent-bg)',
'components-segmented-control-item-active-accent-border': 'var(--color-components-segmented-control-item-active-accent-border)',
'components-option-card-option-bg': 'var(--color-components-option-card-option-bg)',
'components-option-card-option-selected-bg': 'var(--color-components-option-card-option-selected-bg)',
'components-option-card-option-selected-border': 'var(--color-components-option-card-option-selected-border)',
'components-option-card-option-border': 'var(--color-components-option-card-option-border)',
'components-option-card-option-bg-hover': 'var(--color-components-option-card-option-bg-hover)',
'components-option-card-option-border-hover': 'var(--color-components-option-card-option-border-hover)',
'components-tab-active': 'var(--color-components-tab-active)',
'components-badge-white-to-dark': 'var(--color-components-badge-white-to-dark)',
'components-badge-status-light-success-bg': 'var(--color-components-badge-status-light-success-bg)',
'components-badge-status-light-success-border-inner': 'var(--color-components-badge-status-light-success-border-inner)',
'components-badge-status-light-success-halo': 'var(--color-components-badge-status-light-success-halo)',
'components-badge-status-light-border-outer': 'var(--color-components-badge-status-light-border-outer)',
'components-badge-status-light-high-light': 'var(--color-components-badge-status-light-high-light)',
'components-badge-status-light-warning-bg': 'var(--color-components-badge-status-light-warning-bg)',
'components-badge-status-light-warning-border-inner': 'var(--color-components-badge-status-light-warning-border-inner)',
'components-badge-status-light-warning-halo': 'var(--color-components-badge-status-light-warning-halo)',
'components-badge-status-light-error-bg': 'var(--color-components-badge-status-light-error-bg)',
'components-badge-status-light-error-border-inner': 'var(--color-components-badge-status-light-error-border-inner)',
'components-badge-status-light-error-halo': 'var(--color-components-badge-status-light-error-halo)',
'components-badge-status-light-normal-bg': 'var(--color-components-badge-status-light-normal-bg)',
'components-badge-status-light-normal-border-inner': 'var(--color-components-badge-status-light-normal-border-inner)',
'components-badge-status-light-normal-halo': 'var(--color-components-badge-status-light-normal-halo)',
'components-badge-status-light-disabled-bg': 'var(--color-components-badge-status-light-disabled-bg)',
'components-badge-status-light-disabled-border-inner': 'var(--color-components-badge-status-light-disabled-border-inner)',
'components-badge-status-light-disabled-halo': 'var(--color-components-badge-status-light-disabled-halo)',
'components-badge-bg-green-soft': 'var(--color-components-badge-bg-green-soft)',
'components-badge-bg-orange-soft': 'var(--color-components-badge-bg-orange-soft)',
'components-badge-bg-red-soft': 'var(--color-components-badge-bg-red-soft)',
'components-badge-bg-blue-light-soft': 'var(--color-components-badge-bg-blue-light-soft)',
'components-badge-bg-gray-soft': 'var(--color-components-badge-bg-gray-soft)',
'components-badge-bg-dimm': 'var(--color-components-badge-bg-dimm)',
'components-chart-line': 'var(--color-components-chart-line)',
'components-chart-area-1': 'var(--color-components-chart-area-1)',
'components-chart-area-2': 'var(--color-components-chart-area-2)',
'components-chart-current-1': 'var(--color-components-chart-current-1)',
'components-chart-current-2': 'var(--color-components-chart-current-2)',
'components-chart-bg': 'var(--color-components-chart-bg)',
'components-actionbar-bg': 'var(--color-components-actionbar-bg)',
'components-actionbar-border': 'var(--color-components-actionbar-border)',
'components-actionbar-bg-accent': 'var(--color-components-actionbar-bg-accent)',
'components-actionbar-border-accent': 'var(--color-components-actionbar-border-accent)',
'components-dropzone-bg-alt': 'var(--color-components-dropzone-bg-alt)',
'components-dropzone-bg': 'var(--color-components-dropzone-bg)',
'components-dropzone-bg-accent': 'var(--color-components-dropzone-bg-accent)',
'components-dropzone-border': 'var(--color-components-dropzone-border)',
'components-dropzone-border-alt': 'var(--color-components-dropzone-border-alt)',
'components-dropzone-border-accent': 'var(--color-components-dropzone-border-accent)',
'components-progress-brand-progress': 'var(--color-components-progress-brand-progress)',
'components-progress-brand-border': 'var(--color-components-progress-brand-border)',
'components-progress-brand-bg': 'var(--color-components-progress-brand-bg)',
'components-progress-white-progress': 'var(--color-components-progress-white-progress)',
'components-progress-white-border': 'var(--color-components-progress-white-border)',
'components-progress-white-bg': 'var(--color-components-progress-white-bg)',
'components-progress-gray-progress': 'var(--color-components-progress-gray-progress)',
'components-progress-gray-border': 'var(--color-components-progress-gray-border)',
'components-progress-gray-bg': 'var(--color-components-progress-gray-bg)',
'components-progress-warning-progress': 'var(--color-components-progress-warning-progress)',
'components-progress-warning-border': 'var(--color-components-progress-warning-border)',
'components-progress-warning-bg': 'var(--color-components-progress-warning-bg)',
'components-progress-error-progress': 'var(--color-components-progress-error-progress)',
'components-progress-error-border': 'var(--color-components-progress-error-border)',
'components-progress-error-bg': 'var(--color-components-progress-error-bg)',
'components-chat-input-audio-bg': 'var(--color-components-chat-input-audio-bg)',
'components-chat-input-audio-wave-default': 'var(--color-components-chat-input-audio-wave-default)',
'components-chat-input-bg-mask-1': 'var(--color-components-chat-input-bg-mask-1)',
'components-chat-input-bg-mask-2': 'var(--color-components-chat-input-bg-mask-2)',
'components-chat-input-border': 'var(--color-components-chat-input-border)',
'components-chat-input-audio-wave-active': 'var(--color-components-chat-input-audio-wave-active)',
'components-chat-input-audio-bg-alt': 'var(--color-components-chat-input-audio-bg-alt)',
'components-avatar-shape-fill-stop-0': 'var(--color-components-avatar-shape-fill-stop-0)',
'components-avatar-shape-fill-stop-100': 'var(--color-components-avatar-shape-fill-stop-100)',
'components-avatar-bg-mask-stop-0': 'var(--color-components-avatar-bg-mask-stop-0)',
'components-avatar-bg-mask-stop-100': 'var(--color-components-avatar-bg-mask-stop-100)',
'components-avatar-default-avatar-bg': 'var(--color-components-avatar-default-avatar-bg)',
'components-avatar-mask-darkmode-dimmed': 'var(--color-components-avatar-mask-darkmode-dimmed)',
'components-label-gray': 'var(--color-components-label-gray)',
'components-premium-badge-blue-bg-stop-0': 'var(--color-components-premium-badge-blue-bg-stop-0)',
'components-premium-badge-blue-bg-stop-100': 'var(--color-components-premium-badge-blue-bg-stop-100)',
'components-premium-badge-blue-stroke-stop-0': 'var(--color-components-premium-badge-blue-stroke-stop-0)',
'components-premium-badge-blue-stroke-stop-100': 'var(--color-components-premium-badge-blue-stroke-stop-100)',
'components-premium-badge-blue-text-stop-0': 'var(--color-components-premium-badge-blue-text-stop-0)',
'components-premium-badge-blue-text-stop-100': 'var(--color-components-premium-badge-blue-text-stop-100)',
'components-premium-badge-blue-glow': 'var(--color-components-premium-badge-blue-glow)',
'components-premium-badge-blue-bg-stop-0-hover': 'var(--color-components-premium-badge-blue-bg-stop-0-hover)',
'components-premium-badge-blue-bg-stop-100-hover': 'var(--color-components-premium-badge-blue-bg-stop-100-hover)',
'components-premium-badge-blue-glow-hover': 'var(--color-components-premium-badge-blue-glow-hover)',
'components-premium-badge-blue-stroke-stop-0-hover': 'var(--color-components-premium-badge-blue-stroke-stop-0-hover)',
'components-premium-badge-blue-stroke-stop-100-hover': 'var(--color-components-premium-badge-blue-stroke-stop-100-hover)',
'components-premium-badge-highlight-stop-0': 'var(--color-components-premium-badge-highlight-stop-0)',
'components-premium-badge-highlight-stop-100': 'var(--color-components-premium-badge-highlight-stop-100)',
'components-premium-badge-indigo-bg-stop-0': 'var(--color-components-premium-badge-indigo-bg-stop-0)',
'components-premium-badge-indigo-bg-stop-100': 'var(--color-components-premium-badge-indigo-bg-stop-100)',
'components-premium-badge-indigo-stroke-stop-0': 'var(--color-components-premium-badge-indigo-stroke-stop-0)',
'components-premium-badge-indigo-stroke-stop-100': 'var(--color-components-premium-badge-indigo-stroke-stop-100)',
'components-premium-badge-indigo-text-stop-0': 'var(--color-components-premium-badge-indigo-text-stop-0)',
'components-premium-badge-indigo-text-stop-100': 'var(--color-components-premium-badge-indigo-text-stop-100)',
'components-premium-badge-indigo-glow': 'var(--color-components-premium-badge-indigo-glow)',
'components-premium-badge-indigo-glow-hover': 'var(--color-components-premium-badge-indigo-glow-hover)',
'components-premium-badge-indigo-bg-stop-0-hover': 'var(--color-components-premium-badge-indigo-bg-stop-0-hover)',
'components-premium-badge-indigo-bg-stop-100-hover': 'var(--color-components-premium-badge-indigo-bg-stop-100-hover)',
'components-premium-badge-indigo-stroke-stop-0-hover': 'var(--color-components-premium-badge-indigo-stroke-stop-0-hover)',
'components-premium-badge-indigo-stroke-stop-100-hover': 'var(--color-components-premium-badge-indigo-stroke-stop-100-hover)',
'components-premium-badge-grey-bg-stop-0': 'var(--color-components-premium-badge-grey-bg-stop-0)',
'components-premium-badge-grey-bg-stop-100': 'var(--color-components-premium-badge-grey-bg-stop-100)',
'components-premium-badge-grey-stroke-stop-0': 'var(--color-components-premium-badge-grey-stroke-stop-0)',
'components-premium-badge-grey-stroke-stop-100': 'var(--color-components-premium-badge-grey-stroke-stop-100)',
'components-premium-badge-grey-text-stop-0': 'var(--color-components-premium-badge-grey-text-stop-0)',
'components-premium-badge-grey-text-stop-100': 'var(--color-components-premium-badge-grey-text-stop-100)',
'components-premium-badge-grey-glow': 'var(--color-components-premium-badge-grey-glow)',
'components-premium-badge-grey-glow-hover': 'var(--color-components-premium-badge-grey-glow-hover)',
'components-premium-badge-grey-bg-stop-0-hover': 'var(--color-components-premium-badge-grey-bg-stop-0-hover)',
'components-premium-badge-grey-bg-stop-100-hover': 'var(--color-components-premium-badge-grey-bg-stop-100-hover)',
'components-premium-badge-grey-stroke-stop-0-hover': 'var(--color-components-premium-badge-grey-stroke-stop-0-hover)',
'components-premium-badge-grey-stroke-stop-100-hover': 'var(--color-components-premium-badge-grey-stroke-stop-100-hover)',
'components-premium-badge-orange-bg-stop-0': 'var(--color-components-premium-badge-orange-bg-stop-0)',
'components-premium-badge-orange-bg-stop-100': 'var(--color-components-premium-badge-orange-bg-stop-100)',
'components-premium-badge-orange-stroke-stop-0': 'var(--color-components-premium-badge-orange-stroke-stop-0)',
'components-premium-badge-orange-stroke-stop-100': 'var(--color-components-premium-badge-orange-stroke-stop-100)',
'components-premium-badge-orange-text-stop-0': 'var(--color-components-premium-badge-orange-text-stop-0)',
'components-premium-badge-orange-text-stop-100': 'var(--color-components-premium-badge-orange-text-stop-100)',
'components-premium-badge-orange-glow': 'var(--color-components-premium-badge-orange-glow)',
'components-premium-badge-orange-glow-hover': 'var(--color-components-premium-badge-orange-glow-hover)',
'components-premium-badge-orange-bg-stop-0-hover': 'var(--color-components-premium-badge-orange-bg-stop-0-hover)',
'components-premium-badge-orange-bg-stop-100-hover': 'var(--color-components-premium-badge-orange-bg-stop-100-hover)',
'components-premium-badge-orange-stroke-stop-0-hover': 'var(--color-components-premium-badge-orange-stroke-stop-0-hover)',
'components-premium-badge-orange-stroke-stop-100-hover': 'var(--color-components-premium-badge-orange-stroke-stop-100-hover)',
'components-progress-bar-bg': 'var(--color-components-progress-bar-bg)',
'components-progress-bar-progress': 'var(--color-components-progress-bar-progress)',
'components-progress-bar-border': 'var(--color-components-progress-bar-border)',
'components-progress-bar-progress-solid': 'var(--color-components-progress-bar-progress-solid)',
'components-progress-bar-progress-highlight': 'var(--color-components-progress-bar-progress-highlight)',
'components-icon-bg-red-solid': 'var(--color-components-icon-bg-red-solid)',
'components-icon-bg-rose-solid': 'var(--color-components-icon-bg-rose-solid)',
'components-icon-bg-pink-solid': 'var(--color-components-icon-bg-pink-solid)',
'components-icon-bg-orange-dark-solid': 'var(--color-components-icon-bg-orange-dark-solid)',
'components-icon-bg-yellow-solid': 'var(--color-components-icon-bg-yellow-solid)',
'components-icon-bg-green-solid': 'var(--color-components-icon-bg-green-solid)',
'components-icon-bg-teal-solid': 'var(--color-components-icon-bg-teal-solid)',
'components-icon-bg-blue-light-solid': 'var(--color-components-icon-bg-blue-light-solid)',
'components-icon-bg-blue-solid': 'var(--color-components-icon-bg-blue-solid)',
'components-icon-bg-indigo-solid': 'var(--color-components-icon-bg-indigo-solid)',
'components-icon-bg-violet-solid': 'var(--color-components-icon-bg-violet-solid)',
'components-icon-bg-midnight-solid': 'var(--color-components-icon-bg-midnight-solid)',
'components-icon-bg-rose-soft': 'var(--color-components-icon-bg-rose-soft)',
'components-icon-bg-pink-soft': 'var(--color-components-icon-bg-pink-soft)',
'components-icon-bg-orange-dark-soft': 'var(--color-components-icon-bg-orange-dark-soft)',
'components-icon-bg-yellow-soft': 'var(--color-components-icon-bg-yellow-soft)',
'components-icon-bg-green-soft': 'var(--color-components-icon-bg-green-soft)',
'components-icon-bg-teal-soft': 'var(--color-components-icon-bg-teal-soft)',
'components-icon-bg-blue-light-soft': 'var(--color-components-icon-bg-blue-light-soft)',
'components-icon-bg-blue-soft': 'var(--color-components-icon-bg-blue-soft)',
'components-icon-bg-indigo-soft': 'var(--color-components-icon-bg-indigo-soft)',
'components-icon-bg-violet-soft': 'var(--color-components-icon-bg-violet-soft)',
'components-icon-bg-midnight-soft': 'var(--color-components-icon-bg-midnight-soft)',
'components-icon-bg-red-soft': 'var(--color-components-icon-bg-red-soft)',
'components-icon-bg-orange-solid': 'var(--color-components-icon-bg-orange-solid)',
'components-icon-bg-orange-soft': 'var(--color-components-icon-bg-orange-soft)',
'components-marketplace-header-bg': 'var(--color-components-marketplace-header-bg)',
'text-primary': 'var(--color-text-primary)',
'text-secondary': 'var(--color-text-secondary)',
'text-tertiary': 'var(--color-text-tertiary)',
'text-quaternary': 'var(--color-text-quaternary)',
'text-destructive': 'var(--color-text-destructive)',
'text-success': 'var(--color-text-success)',
'text-warning': 'var(--color-text-warning)',
'text-destructive-secondary': 'var(--color-text-destructive-secondary)',
'text-success-secondary': 'var(--color-text-success-secondary)',
'text-warning-secondary': 'var(--color-text-warning-secondary)',
'text-accent': 'var(--color-text-accent)',
'text-primary-on-surface': 'var(--color-text-primary-on-surface)',
'text-placeholder': 'var(--color-text-placeholder)',
'text-disabled': 'var(--color-text-disabled)',
'text-accent-secondary': 'var(--color-text-accent-secondary)',
'text-accent-light-mode-only': 'var(--color-text-accent-light-mode-only)',
'text-text-selected': 'var(--color-text-text-selected)',
'text-secondary-on-surface': 'var(--color-text-secondary-on-surface)',
'text-logo-text': 'var(--color-text-logo-text)',
'text-empty-state-icon': 'var(--color-text-empty-state-icon)',
'text-inverted': 'var(--color-text-inverted)',
'text-inverted-dimmed': 'var(--color-text-inverted-dimmed)',
'background-body': 'var(--color-background-body)',
'background-default-subtle': 'var(--color-background-default-subtle)',
'background-neutral-subtle': 'var(--color-background-neutral-subtle)',
'background-sidenav-bg': 'var(--color-background-sidenav-bg)',
'background-default': 'var(--color-background-default)',
'background-soft': 'var(--color-background-soft)',
'background-gradient-bg-fill-chat-bg-1': 'var(--color-background-gradient-bg-fill-chat-bg-1)',
'background-gradient-bg-fill-chat-bg-2': 'var(--color-background-gradient-bg-fill-chat-bg-2)',
'background-gradient-bg-fill-chat-bubble-bg-1': 'var(--color-background-gradient-bg-fill-chat-bubble-bg-1)',
'background-gradient-bg-fill-chat-bubble-bg-2': 'var(--color-background-gradient-bg-fill-chat-bubble-bg-2)',
'background-gradient-bg-fill-debug-bg-1': 'var(--color-background-gradient-bg-fill-debug-bg-1)',
'background-gradient-bg-fill-debug-bg-2': 'var(--color-background-gradient-bg-fill-debug-bg-2)',
'background-gradient-mask-gray': 'var(--color-background-gradient-mask-gray)',
'background-gradient-mask-transparent': 'var(--color-background-gradient-mask-transparent)',
'background-gradient-mask-input-clear-2': 'var(--color-background-gradient-mask-input-clear-2)',
'background-gradient-mask-input-clear-1': 'var(--color-background-gradient-mask-input-clear-1)',
'background-gradient-mask-transparent-dark': 'var(--color-background-gradient-mask-transparent-dark)',
'background-gradient-mask-side-panel-2': 'var(--color-background-gradient-mask-side-panel-2)',
'background-gradient-mask-side-panel-1': 'var(--color-background-gradient-mask-side-panel-1)',
'background-default-burn': 'var(--color-background-default-burn)',
'background-overlay-fullscreen': 'var(--color-background-overlay-fullscreen)',
'background-default-lighter': 'var(--color-background-default-lighter)',
'background-section': 'var(--color-background-section)',
'background-interaction-from-bg-1': 'var(--color-background-interaction-from-bg-1)',
'background-interaction-from-bg-2': 'var(--color-background-interaction-from-bg-2)',
'background-section-burn': 'var(--color-background-section-burn)',
'background-default-dodge': 'var(--color-background-default-dodge)',
'background-overlay': 'var(--color-background-overlay)',
'background-default-dimmed': 'var(--color-background-default-dimmed)',
'background-default-hover': 'var(--color-background-default-hover)',
'background-overlay-alt': 'var(--color-background-overlay-alt)',
'background-surface-white': 'var(--color-background-surface-white)',
'background-overlay-destructive': 'var(--color-background-overlay-destructive)',
'background-overlay-backdrop': 'var(--color-background-overlay-backdrop)',
'background-body-transparent': 'var(--color-background-body-transparent)',
'background-section-burn-inverted': 'var(--color-background-section-burn-inverted)',
'background-default-hover-alpha-0': 'var(--color-background-default-hover-alpha-0)',
'shadow-shadow-1': 'var(--color-shadow-shadow-1)',
'shadow-shadow-3': 'var(--color-shadow-shadow-3)',
'shadow-shadow-4': 'var(--color-shadow-shadow-4)',
'shadow-shadow-5': 'var(--color-shadow-shadow-5)',
'shadow-shadow-6': 'var(--color-shadow-shadow-6)',
'shadow-shadow-7': 'var(--color-shadow-shadow-7)',
'shadow-shadow-8': 'var(--color-shadow-shadow-8)',
'shadow-shadow-9': 'var(--color-shadow-shadow-9)',
'shadow-shadow-2': 'var(--color-shadow-shadow-2)',
'shadow-shadow-10': 'var(--color-shadow-shadow-10)',
'workflow-block-border': 'var(--color-workflow-block-border)',
'workflow-block-parma-bg': 'var(--color-workflow-block-parma-bg)',
'workflow-block-bg': 'var(--color-workflow-block-bg)',
'workflow-block-bg-transparent': 'var(--color-workflow-block-bg-transparent)',
'workflow-block-border-highlight': 'var(--color-workflow-block-border-highlight)',
'workflow-block-wrapper-bg-1': 'var(--color-workflow-block-wrapper-bg-1)',
'workflow-block-wrapper-bg-2': 'var(--color-workflow-block-wrapper-bg-2)',
'workflow-canvas-workflow-dot-color': 'var(--color-workflow-canvas-workflow-dot-color)',
'workflow-canvas-workflow-bg': 'var(--color-workflow-canvas-workflow-bg)',
'workflow-canvas-workflow-top-bar-1': 'var(--color-workflow-canvas-workflow-top-bar-1)',
'workflow-canvas-workflow-top-bar-2': 'var(--color-workflow-canvas-workflow-top-bar-2)',
'workflow-canvas-canvas-overlay': 'var(--color-workflow-canvas-canvas-overlay)',
'workflow-link-line-active': 'var(--color-workflow-link-line-active)',
'workflow-link-line-normal': 'var(--color-workflow-link-line-normal)',
'workflow-link-line-handle': 'var(--color-workflow-link-line-handle)',
'workflow-link-line-normal-transparent': 'var(--color-workflow-link-line-normal-transparent)',
'workflow-link-line-failure-active': 'var(--color-workflow-link-line-failure-active)',
'workflow-link-line-failure-handle': 'var(--color-workflow-link-line-failure-handle)',
'workflow-link-line-failure-button-bg': 'var(--color-workflow-link-line-failure-button-bg)',
'workflow-link-line-failure-button-hover': 'var(--color-workflow-link-line-failure-button-hover)',
'workflow-link-line-success-active': 'var(--color-workflow-link-line-success-active)',
'workflow-link-line-success-handle': 'var(--color-workflow-link-line-success-handle)',
'workflow-link-line-error-active': 'var(--color-workflow-link-line-error-active)',
'workflow-link-line-error-handle': 'var(--color-workflow-link-line-error-handle)',
'workflow-minimap-bg': 'var(--color-workflow-minimap-bg)',
'workflow-minimap-block': 'var(--color-workflow-minimap-block)',
'workflow-display-success-bg': 'var(--color-workflow-display-success-bg)',
'workflow-display-success-border-1': 'var(--color-workflow-display-success-border-1)',
'workflow-display-success-border-2': 'var(--color-workflow-display-success-border-2)',
'workflow-display-success-vignette-color': 'var(--color-workflow-display-success-vignette-color)',
'workflow-display-success-bg-line-pattern': 'var(--color-workflow-display-success-bg-line-pattern)',
'workflow-display-glass-1': 'var(--color-workflow-display-glass-1)',
'workflow-display-glass-2': 'var(--color-workflow-display-glass-2)',
'workflow-display-vignette-dark': 'var(--color-workflow-display-vignette-dark)',
'workflow-display-highlight': 'var(--color-workflow-display-highlight)',
'workflow-display-outline': 'var(--color-workflow-display-outline)',
'workflow-display-error-bg': 'var(--color-workflow-display-error-bg)',
'workflow-display-error-bg-line-pattern': 'var(--color-workflow-display-error-bg-line-pattern)',
'workflow-display-error-border-1': 'var(--color-workflow-display-error-border-1)',
'workflow-display-error-border-2': 'var(--color-workflow-display-error-border-2)',
'workflow-display-error-vignette-color': 'var(--color-workflow-display-error-vignette-color)',
'workflow-display-warning-bg': 'var(--color-workflow-display-warning-bg)',
'workflow-display-warning-bg-line-pattern': 'var(--color-workflow-display-warning-bg-line-pattern)',
'workflow-display-warning-border-1': 'var(--color-workflow-display-warning-border-1)',
'workflow-display-warning-border-2': 'var(--color-workflow-display-warning-border-2)',
'workflow-display-warning-vignette-color': 'var(--color-workflow-display-warning-vignette-color)',
'workflow-display-normal-bg': 'var(--color-workflow-display-normal-bg)',
'workflow-display-normal-bg-line-pattern': 'var(--color-workflow-display-normal-bg-line-pattern)',
'workflow-display-normal-border-1': 'var(--color-workflow-display-normal-border-1)',
'workflow-display-normal-border-2': 'var(--color-workflow-display-normal-border-2)',
'workflow-display-normal-vignette-color': 'var(--color-workflow-display-normal-vignette-color)',
'workflow-display-disabled-bg': 'var(--color-workflow-display-disabled-bg)',
'workflow-display-disabled-bg-line-pattern': 'var(--color-workflow-display-disabled-bg-line-pattern)',
'workflow-display-disabled-border-1': 'var(--color-workflow-display-disabled-border-1)',
'workflow-display-disabled-border-2': 'var(--color-workflow-display-disabled-border-2)',
'workflow-display-disabled-vignette-color': 'var(--color-workflow-display-disabled-vignette-color)',
'workflow-display-disabled-outline': 'var(--color-workflow-display-disabled-outline)',
'workflow-workflow-progress-bg-1': 'var(--color-workflow-workflow-progress-bg-1)',
'workflow-workflow-progress-bg-2': 'var(--color-workflow-workflow-progress-bg-2)',
'workflow-debug-run-status-bg': 'var(--color-workflow-debug-run-status-bg)',
'workflow-debug-breakpoint': 'var(--color-workflow-debug-breakpoint)',
'workflow-debug-text': 'var(--color-workflow-debug-text)',
'workflow-debug-text-disabled': 'var(--color-workflow-debug-text-disabled)',
'workflow-debug-run-status-bg-alt': 'var(--color-workflow-debug-run-status-bg-alt)',
'workflow-test-run-run-status-bg': 'var(--color-workflow-test-run-run-status-bg)',
'workflow-test-run-text': 'var(--color-workflow-test-run-text)',
'workflow-test-run-run-status-bg-alt': 'var(--color-workflow-test-run-run-status-bg-alt)',
'workflow-test-run-paused-bg': 'var(--color-workflow-test-run-paused-bg)',
'workflow-test-run-paused-text': 'var(--color-workflow-test-run-paused-text)',
'divider-subtle': 'var(--color-divider-subtle)',
'divider-regular': 'var(--color-divider-regular)',
'divider-deep': 'var(--color-divider-deep)',
'divider-burn': 'var(--color-divider-burn)',
'divider-intense': 'var(--color-divider-intense)',
'divider-solid': 'var(--color-divider-solid)',
'divider-solid-alt': 'var(--color-divider-solid-alt)',
'divider-accent': 'var(--color-divider-accent)',
'state-base-hover': 'var(--color-state-base-hover)',
'state-base-active': 'var(--color-state-base-active)',
'state-base-hover-alt': 'var(--color-state-base-hover-alt)',
'state-base-handle': 'var(--color-state-base-handle)',
'state-base-handle-hover': 'var(--color-state-base-handle-hover)',
'state-base-hover-subtle': 'var(--color-state-base-hover-subtle)',
'state-accent-hover': 'var(--color-state-accent-hover)',
'state-accent-active': 'var(--color-state-accent-active)',
'state-accent-hover-alt': 'var(--color-state-accent-hover-alt)',
'state-accent-solid': 'var(--color-state-accent-solid)',
'state-accent-active-alt': 'var(--color-state-accent-active-alt)',
'state-destructive-hover': 'var(--color-state-destructive-hover)',
'state-destructive-hover-alt': 'var(--color-state-destructive-hover-alt)',
'state-destructive-active': 'var(--color-state-destructive-active)',
'state-destructive-solid': 'var(--color-state-destructive-solid)',
'state-destructive-border': 'var(--color-state-destructive-border)',
'state-destructive-hover-transparent': 'var(--color-state-destructive-hover-transparent)',
'state-success-hover': 'var(--color-state-success-hover)',
'state-success-hover-alt': 'var(--color-state-success-hover-alt)',
'state-success-active': 'var(--color-state-success-active)',
'state-success-solid': 'var(--color-state-success-solid)',
'state-warning-hover': 'var(--color-state-warning-hover)',
'state-warning-hover-alt': 'var(--color-state-warning-hover-alt)',
'state-warning-active': 'var(--color-state-warning-active)',
'state-warning-solid': 'var(--color-state-warning-solid)',
'state-warning-hover-transparent': 'var(--color-state-warning-hover-transparent)',
'effects-highlight': 'var(--color-effects-highlight)',
'effects-highlight-lightmode-off': 'var(--color-effects-highlight-lightmode-off)',
'effects-image-frame': 'var(--color-effects-image-frame)',
'effects-icon-border': 'var(--color-effects-icon-border)',
'effects-highlight-subtle': 'var(--color-effects-highlight-subtle)',
'util-colors-orange-dark-orange-dark-50': 'var(--color-util-colors-orange-dark-orange-dark-50)',
'util-colors-orange-dark-orange-dark-100': 'var(--color-util-colors-orange-dark-orange-dark-100)',
'util-colors-orange-dark-orange-dark-200': 'var(--color-util-colors-orange-dark-orange-dark-200)',
'util-colors-orange-dark-orange-dark-300': 'var(--color-util-colors-orange-dark-orange-dark-300)',
'util-colors-orange-dark-orange-dark-400': 'var(--color-util-colors-orange-dark-orange-dark-400)',
'util-colors-orange-dark-orange-dark-500': 'var(--color-util-colors-orange-dark-orange-dark-500)',
'util-colors-orange-dark-orange-dark-600': 'var(--color-util-colors-orange-dark-orange-dark-600)',
'util-colors-orange-dark-orange-dark-700': 'var(--color-util-colors-orange-dark-orange-dark-700)',
'util-colors-orange-orange-50': 'var(--color-util-colors-orange-orange-50)',
'util-colors-orange-orange-100': 'var(--color-util-colors-orange-orange-100)',
'util-colors-orange-orange-200': 'var(--color-util-colors-orange-orange-200)',
'util-colors-orange-orange-300': 'var(--color-util-colors-orange-orange-300)',
'util-colors-orange-orange-400': 'var(--color-util-colors-orange-orange-400)',
'util-colors-orange-orange-500': 'var(--color-util-colors-orange-orange-500)',
'util-colors-orange-orange-600': 'var(--color-util-colors-orange-orange-600)',
'util-colors-orange-orange-700': 'var(--color-util-colors-orange-orange-700)',
'util-colors-orange-orange-100-transparent': 'var(--color-util-colors-orange-orange-100-transparent)',
'util-colors-pink-pink-50': 'var(--color-util-colors-pink-pink-50)',
'util-colors-pink-pink-100': 'var(--color-util-colors-pink-pink-100)',
'util-colors-pink-pink-200': 'var(--color-util-colors-pink-pink-200)',
'util-colors-pink-pink-300': 'var(--color-util-colors-pink-pink-300)',
'util-colors-pink-pink-400': 'var(--color-util-colors-pink-pink-400)',
'util-colors-pink-pink-500': 'var(--color-util-colors-pink-pink-500)',
'util-colors-pink-pink-600': 'var(--color-util-colors-pink-pink-600)',
'util-colors-pink-pink-700': 'var(--color-util-colors-pink-pink-700)',
'util-colors-fuchsia-fuchsia-50': 'var(--color-util-colors-fuchsia-fuchsia-50)',
'util-colors-fuchsia-fuchsia-100': 'var(--color-util-colors-fuchsia-fuchsia-100)',
'util-colors-fuchsia-fuchsia-200': 'var(--color-util-colors-fuchsia-fuchsia-200)',
'util-colors-fuchsia-fuchsia-300': 'var(--color-util-colors-fuchsia-fuchsia-300)',
'util-colors-fuchsia-fuchsia-400': 'var(--color-util-colors-fuchsia-fuchsia-400)',
'util-colors-fuchsia-fuchsia-500': 'var(--color-util-colors-fuchsia-fuchsia-500)',
'util-colors-fuchsia-fuchsia-600': 'var(--color-util-colors-fuchsia-fuchsia-600)',
'util-colors-fuchsia-fuchsia-700': 'var(--color-util-colors-fuchsia-fuchsia-700)',
'util-colors-purple-purple-50': 'var(--color-util-colors-purple-purple-50)',
'util-colors-purple-purple-100': 'var(--color-util-colors-purple-purple-100)',
'util-colors-purple-purple-200': 'var(--color-util-colors-purple-purple-200)',
'util-colors-purple-purple-300': 'var(--color-util-colors-purple-purple-300)',
'util-colors-purple-purple-400': 'var(--color-util-colors-purple-purple-400)',
'util-colors-purple-purple-500': 'var(--color-util-colors-purple-purple-500)',
'util-colors-purple-purple-600': 'var(--color-util-colors-purple-purple-600)',
'util-colors-purple-purple-700': 'var(--color-util-colors-purple-purple-700)',
'util-colors-indigo-indigo-50': 'var(--color-util-colors-indigo-indigo-50)',
'util-colors-indigo-indigo-100': 'var(--color-util-colors-indigo-indigo-100)',
'util-colors-indigo-indigo-200': 'var(--color-util-colors-indigo-indigo-200)',
'util-colors-indigo-indigo-300': 'var(--color-util-colors-indigo-indigo-300)',
'util-colors-indigo-indigo-400': 'var(--color-util-colors-indigo-indigo-400)',
'util-colors-indigo-indigo-500': 'var(--color-util-colors-indigo-indigo-500)',
'util-colors-indigo-indigo-600': 'var(--color-util-colors-indigo-indigo-600)',
'util-colors-indigo-indigo-700': 'var(--color-util-colors-indigo-indigo-700)',
'util-colors-blue-blue-50': 'var(--color-util-colors-blue-blue-50)',
'util-colors-blue-blue-100': 'var(--color-util-colors-blue-blue-100)',
'util-colors-blue-blue-200': 'var(--color-util-colors-blue-blue-200)',
'util-colors-blue-blue-300': 'var(--color-util-colors-blue-blue-300)',
'util-colors-blue-blue-400': 'var(--color-util-colors-blue-blue-400)',
'util-colors-blue-blue-500': 'var(--color-util-colors-blue-blue-500)',
'util-colors-blue-blue-600': 'var(--color-util-colors-blue-blue-600)',
'util-colors-blue-blue-700': 'var(--color-util-colors-blue-blue-700)',
'util-colors-blue-light-blue-light-50': 'var(--color-util-colors-blue-light-blue-light-50)',
'util-colors-blue-light-blue-light-100': 'var(--color-util-colors-blue-light-blue-light-100)',
'util-colors-blue-light-blue-light-200': 'var(--color-util-colors-blue-light-blue-light-200)',
'util-colors-blue-light-blue-light-300': 'var(--color-util-colors-blue-light-blue-light-300)',
'util-colors-blue-light-blue-light-400': 'var(--color-util-colors-blue-light-blue-light-400)',
'util-colors-blue-light-blue-light-500': 'var(--color-util-colors-blue-light-blue-light-500)',
'util-colors-blue-light-blue-light-600': 'var(--color-util-colors-blue-light-blue-light-600)',
'util-colors-blue-light-blue-light-700': 'var(--color-util-colors-blue-light-blue-light-700)',
'util-colors-gray-blue-gray-blue-50': 'var(--color-util-colors-gray-blue-gray-blue-50)',
'util-colors-gray-blue-gray-blue-100': 'var(--color-util-colors-gray-blue-gray-blue-100)',
'util-colors-gray-blue-gray-blue-200': 'var(--color-util-colors-gray-blue-gray-blue-200)',
'util-colors-gray-blue-gray-blue-300': 'var(--color-util-colors-gray-blue-gray-blue-300)',
'util-colors-gray-blue-gray-blue-400': 'var(--color-util-colors-gray-blue-gray-blue-400)',
'util-colors-gray-blue-gray-blue-500': 'var(--color-util-colors-gray-blue-gray-blue-500)',
'util-colors-gray-blue-gray-blue-600': 'var(--color-util-colors-gray-blue-gray-blue-600)',
'util-colors-gray-blue-gray-blue-700': 'var(--color-util-colors-gray-blue-gray-blue-700)',
'util-colors-blue-brand-blue-brand-50': 'var(--color-util-colors-blue-brand-blue-brand-50)',
'util-colors-blue-brand-blue-brand-100': 'var(--color-util-colors-blue-brand-blue-brand-100)',
'util-colors-blue-brand-blue-brand-200': 'var(--color-util-colors-blue-brand-blue-brand-200)',
'util-colors-blue-brand-blue-brand-300': 'var(--color-util-colors-blue-brand-blue-brand-300)',
'util-colors-blue-brand-blue-brand-400': 'var(--color-util-colors-blue-brand-blue-brand-400)',
'util-colors-blue-brand-blue-brand-500': 'var(--color-util-colors-blue-brand-blue-brand-500)',
'util-colors-blue-brand-blue-brand-600': 'var(--color-util-colors-blue-brand-blue-brand-600)',
'util-colors-blue-brand-blue-brand-700': 'var(--color-util-colors-blue-brand-blue-brand-700)',
'util-colors-red-red-50': 'var(--color-util-colors-red-red-50)',
'util-colors-red-red-100': 'var(--color-util-colors-red-red-100)',
'util-colors-red-red-200': 'var(--color-util-colors-red-red-200)',
'util-colors-red-red-300': 'var(--color-util-colors-red-red-300)',
'util-colors-red-red-400': 'var(--color-util-colors-red-red-400)',
'util-colors-red-red-500': 'var(--color-util-colors-red-red-500)',
'util-colors-red-red-600': 'var(--color-util-colors-red-red-600)',
'util-colors-red-red-700': 'var(--color-util-colors-red-red-700)',
'util-colors-green-green-50': 'var(--color-util-colors-green-green-50)',
'util-colors-green-green-100': 'var(--color-util-colors-green-green-100)',
'util-colors-green-green-200': 'var(--color-util-colors-green-green-200)',
'util-colors-green-green-300': 'var(--color-util-colors-green-green-300)',
'util-colors-green-green-400': 'var(--color-util-colors-green-green-400)',
'util-colors-green-green-500': 'var(--color-util-colors-green-green-500)',
'util-colors-green-green-600': 'var(--color-util-colors-green-green-600)',
'util-colors-green-green-700': 'var(--color-util-colors-green-green-700)',
'util-colors-warning-warning-50': 'var(--color-util-colors-warning-warning-50)',
'util-colors-warning-warning-100': 'var(--color-util-colors-warning-warning-100)',
'util-colors-warning-warning-200': 'var(--color-util-colors-warning-warning-200)',
'util-colors-warning-warning-300': 'var(--color-util-colors-warning-warning-300)',
'util-colors-warning-warning-400': 'var(--color-util-colors-warning-warning-400)',
'util-colors-warning-warning-500': 'var(--color-util-colors-warning-warning-500)',
'util-colors-warning-warning-600': 'var(--color-util-colors-warning-warning-600)',
'util-colors-warning-warning-700': 'var(--color-util-colors-warning-warning-700)',
'util-colors-yellow-yellow-50': 'var(--color-util-colors-yellow-yellow-50)',
'util-colors-yellow-yellow-100': 'var(--color-util-colors-yellow-yellow-100)',
'util-colors-yellow-yellow-200': 'var(--color-util-colors-yellow-yellow-200)',
'util-colors-yellow-yellow-300': 'var(--color-util-colors-yellow-yellow-300)',
'util-colors-yellow-yellow-400': 'var(--color-util-colors-yellow-yellow-400)',
'util-colors-yellow-yellow-500': 'var(--color-util-colors-yellow-yellow-500)',
'util-colors-yellow-yellow-600': 'var(--color-util-colors-yellow-yellow-600)',
'util-colors-yellow-yellow-700': 'var(--color-util-colors-yellow-yellow-700)',
'util-colors-teal-teal-50': 'var(--color-util-colors-teal-teal-50)',
'util-colors-teal-teal-100': 'var(--color-util-colors-teal-teal-100)',
'util-colors-teal-teal-200': 'var(--color-util-colors-teal-teal-200)',
'util-colors-teal-teal-300': 'var(--color-util-colors-teal-teal-300)',
'util-colors-teal-teal-400': 'var(--color-util-colors-teal-teal-400)',
'util-colors-teal-teal-500': 'var(--color-util-colors-teal-teal-500)',
'util-colors-teal-teal-600': 'var(--color-util-colors-teal-teal-600)',
'util-colors-teal-teal-700': 'var(--color-util-colors-teal-teal-700)',
'util-colors-cyan-cyan-50': 'var(--color-util-colors-cyan-cyan-50)',
'util-colors-cyan-cyan-100': 'var(--color-util-colors-cyan-cyan-100)',
'util-colors-cyan-cyan-200': 'var(--color-util-colors-cyan-cyan-200)',
'util-colors-cyan-cyan-300': 'var(--color-util-colors-cyan-cyan-300)',
'util-colors-cyan-cyan-400': 'var(--color-util-colors-cyan-cyan-400)',
'util-colors-cyan-cyan-500': 'var(--color-util-colors-cyan-cyan-500)',
'util-colors-cyan-cyan-600': 'var(--color-util-colors-cyan-cyan-600)',
'util-colors-cyan-cyan-700': 'var(--color-util-colors-cyan-cyan-700)',
'util-colors-violet-violet-50': 'var(--color-util-colors-violet-violet-50)',
'util-colors-violet-violet-100': 'var(--color-util-colors-violet-violet-100)',
'util-colors-violet-violet-200': 'var(--color-util-colors-violet-violet-200)',
'util-colors-violet-violet-300': 'var(--color-util-colors-violet-violet-300)',
'util-colors-violet-violet-400': 'var(--color-util-colors-violet-violet-400)',
'util-colors-violet-violet-500': 'var(--color-util-colors-violet-violet-500)',
'util-colors-violet-violet-600': 'var(--color-util-colors-violet-violet-600)',
'util-colors-violet-violet-700': 'var(--color-util-colors-violet-violet-700)',
'util-colors-gray-gray-50': 'var(--color-util-colors-gray-gray-50)',
'util-colors-gray-gray-100': 'var(--color-util-colors-gray-gray-100)',
'util-colors-gray-gray-200': 'var(--color-util-colors-gray-gray-200)',
'util-colors-gray-gray-300': 'var(--color-util-colors-gray-gray-300)',
'util-colors-gray-gray-400': 'var(--color-util-colors-gray-gray-400)',
'util-colors-gray-gray-500': 'var(--color-util-colors-gray-gray-500)',
'util-colors-gray-gray-600': 'var(--color-util-colors-gray-gray-600)',
'util-colors-gray-gray-700': 'var(--color-util-colors-gray-gray-700)',
'util-colors-green-light-green-light-50': 'var(--color-util-colors-green-light-green-light-50)',
'util-colors-green-light-green-light-100': 'var(--color-util-colors-green-light-green-light-100)',
'util-colors-green-light-green-light-200': 'var(--color-util-colors-green-light-green-light-200)',
'util-colors-green-light-green-light-300': 'var(--color-util-colors-green-light-green-light-300)',
'util-colors-green-light-green-light-500': 'var(--color-util-colors-green-light-green-light-500)',
'util-colors-green-light-green-light-400': 'var(--color-util-colors-green-light-green-light-400)',
'util-colors-green-light-green-light-600': 'var(--color-util-colors-green-light-green-light-600)',
'util-colors-green-light-green-light-700': 'var(--color-util-colors-green-light-green-light-700)',
'util-colors-rose-rose-50': 'var(--color-util-colors-rose-rose-50)',
'util-colors-rose-rose-100': 'var(--color-util-colors-rose-rose-100)',
'util-colors-rose-rose-200': 'var(--color-util-colors-rose-rose-200)',
'util-colors-rose-rose-300': 'var(--color-util-colors-rose-rose-300)',
'util-colors-rose-rose-400': 'var(--color-util-colors-rose-rose-400)',
'util-colors-rose-rose-500': 'var(--color-util-colors-rose-rose-500)',
'util-colors-rose-rose-600': 'var(--color-util-colors-rose-rose-600)',
'util-colors-rose-rose-700': 'var(--color-util-colors-rose-rose-700)',
'util-colors-midnight-midnight-50': 'var(--color-util-colors-midnight-midnight-50)',
'util-colors-midnight-midnight-100': 'var(--color-util-colors-midnight-midnight-100)',
'util-colors-midnight-midnight-200': 'var(--color-util-colors-midnight-midnight-200)',
'util-colors-midnight-midnight-300': 'var(--color-util-colors-midnight-midnight-300)',
'util-colors-midnight-midnight-400': 'var(--color-util-colors-midnight-midnight-400)',
'util-colors-midnight-midnight-500': 'var(--color-util-colors-midnight-midnight-500)',
'util-colors-midnight-midnight-600': 'var(--color-util-colors-midnight-midnight-600)',
'util-colors-midnight-midnight-700': 'var(--color-util-colors-midnight-midnight-700)',
'third-party-LangChain': 'var(--color-third-party-LangChain)',
'third-party-Langfuse': 'var(--color-third-party-Langfuse)',
'third-party-Github': 'var(--color-third-party-Github)',
'third-party-Github-tertiary': 'var(--color-third-party-Github-tertiary)',
'third-party-Github-secondary': 'var(--color-third-party-Github-secondary)',
'third-party-model-bg-openai': 'var(--color-third-party-model-bg-openai)',
'third-party-model-bg-anthropic': 'var(--color-third-party-model-bg-anthropic)',
'third-party-model-bg-default': 'var(--color-third-party-model-bg-default)',
'third-party-aws': 'var(--color-third-party-aws)',
'third-party-aws-alt': 'var(--color-third-party-aws-alt)',
'saas-background': 'var(--color-saas-background)',
'saas-pricing-grid-bg': 'var(--color-saas-pricing-grid-bg)',
'saas-dify-blue-static': 'var(--color-saas-dify-blue-static)',
'saas-dify-blue-static-hover': 'var(--color-saas-dify-blue-static-hover)',
'saas-dify-blue-accessible': 'var(--color-saas-dify-blue-accessible)',
'saas-dify-blue-inverted': 'var(--color-saas-dify-blue-inverted)',
'saas-dify-blue-inverted-dimmed': 'var(--color-saas-dify-blue-inverted-dimmed)',
'saas-background-inverted': 'var(--color-saas-background-inverted)',
'saas-background-inverted-hover': 'var(--color-saas-background-inverted-hover)',
'dify-logo-blue': 'var(--color-dify-logo-blue)',
'dify-logo-black': 'var(--color-dify-logo-black)',
'dify-logo-outline-1': 'var(--color-dify-logo-outline-1)',
'dify-logo-outline-2': 'var(--color-dify-logo-outline-2)',
}
export default vars

View File

@ -0,0 +1,772 @@
/* Attention: Generated. Do not edit by hand. */
/*
* Semantic design tokens. Each entry registers a Tailwind v4 utility
* (e.g. bg-components-input-bg-normal) that resolves to var(--color-...).
* Runtime values come from themes/light.css and themes/dark.css scoped
* under html[data-theme=...] @theme inline avoids duplicating them at :root.
*/
@theme inline {
--color-components-input-bg-normal: var(--color-components-input-bg-normal);
--color-components-input-text-placeholder: var(--color-components-input-text-placeholder);
--color-components-input-bg-hover: var(--color-components-input-bg-hover);
--color-components-input-bg-active: var(--color-components-input-bg-active);
--color-components-input-border-active: var(--color-components-input-border-active);
--color-components-input-border-destructive: var(--color-components-input-border-destructive);
--color-components-input-text-filled: var(--color-components-input-text-filled);
--color-components-input-bg-destructive: var(--color-components-input-bg-destructive);
--color-components-input-bg-disabled: var(--color-components-input-bg-disabled);
--color-components-input-text-disabled: var(--color-components-input-text-disabled);
--color-components-input-text-filled-disabled: var(--color-components-input-text-filled-disabled);
--color-components-input-border-hover: var(--color-components-input-border-hover);
--color-components-input-border-active-prompt-1: var(--color-components-input-border-active-prompt-1);
--color-components-input-border-active-prompt-2: var(--color-components-input-border-active-prompt-2);
--color-components-kbd-bg-gray: var(--color-components-kbd-bg-gray);
--color-components-kbd-bg-white: var(--color-components-kbd-bg-white);
--color-components-tooltip-bg: var(--color-components-tooltip-bg);
--color-components-button-primary-text: var(--color-components-button-primary-text);
--color-components-button-primary-bg: var(--color-components-button-primary-bg);
--color-components-button-primary-border: var(--color-components-button-primary-border);
--color-components-button-primary-bg-hover: var(--color-components-button-primary-bg-hover);
--color-components-button-primary-border-hover: var(--color-components-button-primary-border-hover);
--color-components-button-primary-bg-disabled: var(--color-components-button-primary-bg-disabled);
--color-components-button-primary-border-disabled: var(--color-components-button-primary-border-disabled);
--color-components-button-primary-text-disabled: var(--color-components-button-primary-text-disabled);
--color-components-button-secondary-text: var(--color-components-button-secondary-text);
--color-components-button-secondary-text-disabled: var(--color-components-button-secondary-text-disabled);
--color-components-button-secondary-bg: var(--color-components-button-secondary-bg);
--color-components-button-secondary-bg-hover: var(--color-components-button-secondary-bg-hover);
--color-components-button-secondary-bg-disabled: var(--color-components-button-secondary-bg-disabled);
--color-components-button-secondary-border: var(--color-components-button-secondary-border);
--color-components-button-secondary-border-hover: var(--color-components-button-secondary-border-hover);
--color-components-button-secondary-border-disabled: var(--color-components-button-secondary-border-disabled);
--color-components-button-tertiary-text: var(--color-components-button-tertiary-text);
--color-components-button-tertiary-text-disabled: var(--color-components-button-tertiary-text-disabled);
--color-components-button-tertiary-bg: var(--color-components-button-tertiary-bg);
--color-components-button-tertiary-bg-hover: var(--color-components-button-tertiary-bg-hover);
--color-components-button-tertiary-bg-disabled: var(--color-components-button-tertiary-bg-disabled);
--color-components-button-ghost-text: var(--color-components-button-ghost-text);
--color-components-button-ghost-text-disabled: var(--color-components-button-ghost-text-disabled);
--color-components-button-ghost-bg-hover: var(--color-components-button-ghost-bg-hover);
--color-components-button-destructive-primary-text: var(--color-components-button-destructive-primary-text);
--color-components-button-destructive-primary-text-disabled: var(--color-components-button-destructive-primary-text-disabled);
--color-components-button-destructive-primary-bg: var(--color-components-button-destructive-primary-bg);
--color-components-button-destructive-primary-bg-hover: var(--color-components-button-destructive-primary-bg-hover);
--color-components-button-destructive-primary-bg-disabled: var(--color-components-button-destructive-primary-bg-disabled);
--color-components-button-destructive-primary-border: var(--color-components-button-destructive-primary-border);
--color-components-button-destructive-primary-border-hover: var(--color-components-button-destructive-primary-border-hover);
--color-components-button-destructive-primary-border-disabled: var(--color-components-button-destructive-primary-border-disabled);
--color-components-button-destructive-secondary-text: var(--color-components-button-destructive-secondary-text);
--color-components-button-destructive-secondary-text-disabled: var(--color-components-button-destructive-secondary-text-disabled);
--color-components-button-destructive-secondary-bg: var(--color-components-button-destructive-secondary-bg);
--color-components-button-destructive-secondary-bg-hover: var(--color-components-button-destructive-secondary-bg-hover);
--color-components-button-destructive-secondary-bg-disabled: var(--color-components-button-destructive-secondary-bg-disabled);
--color-components-button-destructive-secondary-border: var(--color-components-button-destructive-secondary-border);
--color-components-button-destructive-secondary-border-hover: var(--color-components-button-destructive-secondary-border-hover);
--color-components-button-destructive-secondary-border-disabled: var(--color-components-button-destructive-secondary-border-disabled);
--color-components-button-destructive-tertiary-text: var(--color-components-button-destructive-tertiary-text);
--color-components-button-destructive-tertiary-text-disabled: var(--color-components-button-destructive-tertiary-text-disabled);
--color-components-button-destructive-tertiary-bg: var(--color-components-button-destructive-tertiary-bg);
--color-components-button-destructive-tertiary-bg-hover: var(--color-components-button-destructive-tertiary-bg-hover);
--color-components-button-destructive-tertiary-bg-disabled: var(--color-components-button-destructive-tertiary-bg-disabled);
--color-components-button-destructive-ghost-text: var(--color-components-button-destructive-ghost-text);
--color-components-button-destructive-ghost-text-disabled: var(--color-components-button-destructive-ghost-text-disabled);
--color-components-button-destructive-ghost-bg-hover: var(--color-components-button-destructive-ghost-bg-hover);
--color-components-button-secondary-accent-text: var(--color-components-button-secondary-accent-text);
--color-components-button-secondary-accent-text-disabled: var(--color-components-button-secondary-accent-text-disabled);
--color-components-button-secondary-accent-bg: var(--color-components-button-secondary-accent-bg);
--color-components-button-secondary-accent-bg-hover: var(--color-components-button-secondary-accent-bg-hover);
--color-components-button-secondary-accent-bg-disabled: var(--color-components-button-secondary-accent-bg-disabled);
--color-components-button-secondary-accent-border: var(--color-components-button-secondary-accent-border);
--color-components-button-secondary-accent-border-hover: var(--color-components-button-secondary-accent-border-hover);
--color-components-button-secondary-accent-border-disabled: var(--color-components-button-secondary-accent-border-disabled);
--color-components-button-indigo-bg: var(--color-components-button-indigo-bg);
--color-components-button-indigo-bg-hover: var(--color-components-button-indigo-bg-hover);
--color-components-button-indigo-bg-disabled: var(--color-components-button-indigo-bg-disabled);
--color-components-checkbox-icon: var(--color-components-checkbox-icon);
--color-components-checkbox-icon-disabled: var(--color-components-checkbox-icon-disabled);
--color-components-checkbox-bg: var(--color-components-checkbox-bg);
--color-components-checkbox-bg-hover: var(--color-components-checkbox-bg-hover);
--color-components-checkbox-bg-disabled: var(--color-components-checkbox-bg-disabled);
--color-components-checkbox-border: var(--color-components-checkbox-border);
--color-components-checkbox-border-hover: var(--color-components-checkbox-border-hover);
--color-components-checkbox-border-disabled: var(--color-components-checkbox-border-disabled);
--color-components-checkbox-bg-unchecked: var(--color-components-checkbox-bg-unchecked);
--color-components-checkbox-bg-unchecked-hover: var(--color-components-checkbox-bg-unchecked-hover);
--color-components-checkbox-bg-disabled-checked: var(--color-components-checkbox-bg-disabled-checked);
--color-components-radio-border-checked: var(--color-components-radio-border-checked);
--color-components-radio-border-checked-hover: var(--color-components-radio-border-checked-hover);
--color-components-radio-border-checked-disabled: var(--color-components-radio-border-checked-disabled);
--color-components-radio-bg-disabled: var(--color-components-radio-bg-disabled);
--color-components-radio-border: var(--color-components-radio-border);
--color-components-radio-border-hover: var(--color-components-radio-border-hover);
--color-components-radio-border-disabled: var(--color-components-radio-border-disabled);
--color-components-radio-bg: var(--color-components-radio-bg);
--color-components-radio-bg-hover: var(--color-components-radio-bg-hover);
--color-components-toggle-knob: var(--color-components-toggle-knob);
--color-components-toggle-knob-disabled: var(--color-components-toggle-knob-disabled);
--color-components-toggle-bg: var(--color-components-toggle-bg);
--color-components-toggle-bg-hover: var(--color-components-toggle-bg-hover);
--color-components-toggle-bg-disabled: var(--color-components-toggle-bg-disabled);
--color-components-toggle-bg-unchecked: var(--color-components-toggle-bg-unchecked);
--color-components-toggle-bg-unchecked-hover: var(--color-components-toggle-bg-unchecked-hover);
--color-components-toggle-bg-unchecked-disabled: var(--color-components-toggle-bg-unchecked-disabled);
--color-components-toggle-knob-hover: var(--color-components-toggle-knob-hover);
--color-components-card-bg: var(--color-components-card-bg);
--color-components-card-border: var(--color-components-card-border);
--color-components-card-bg-alt: var(--color-components-card-bg-alt);
--color-components-card-bg-transparent: var(--color-components-card-bg-transparent);
--color-components-card-bg-alt-transparent: var(--color-components-card-bg-alt-transparent);
--color-components-menu-item-text: var(--color-components-menu-item-text);
--color-components-menu-item-text-active: var(--color-components-menu-item-text-active);
--color-components-menu-item-text-hover: var(--color-components-menu-item-text-hover);
--color-components-menu-item-text-active-accent: var(--color-components-menu-item-text-active-accent);
--color-components-menu-item-bg-active: var(--color-components-menu-item-bg-active);
--color-components-menu-item-bg-hover: var(--color-components-menu-item-bg-hover);
--color-components-panel-bg: var(--color-components-panel-bg);
--color-components-panel-bg-blur: var(--color-components-panel-bg-blur);
--color-components-panel-border: var(--color-components-panel-border);
--color-components-panel-border-subtle: var(--color-components-panel-border-subtle);
--color-components-panel-gradient-2: var(--color-components-panel-gradient-2);
--color-components-panel-gradient-1: var(--color-components-panel-gradient-1);
--color-components-panel-bg-alt: var(--color-components-panel-bg-alt);
--color-components-panel-on-panel-item-bg: var(--color-components-panel-on-panel-item-bg);
--color-components-panel-on-panel-item-bg-hover: var(--color-components-panel-on-panel-item-bg-hover);
--color-components-panel-on-panel-item-bg-alt: var(--color-components-panel-on-panel-item-bg-alt);
--color-components-panel-on-panel-item-bg-transparent: var(--color-components-panel-on-panel-item-bg-transparent);
--color-components-panel-on-panel-item-bg-hover-transparent: var(--color-components-panel-on-panel-item-bg-hover-transparent);
--color-components-panel-on-panel-item-bg-destructive-hover-transparent: var(--color-components-panel-on-panel-item-bg-destructive-hover-transparent);
--color-components-panel-bg-transparent: var(--color-components-panel-bg-transparent);
--color-components-main-nav-nav-button-text: var(--color-components-main-nav-nav-button-text);
--color-components-main-nav-nav-button-text-active: var(--color-components-main-nav-nav-button-text-active);
--color-components-main-nav-nav-button-bg: var(--color-components-main-nav-nav-button-bg);
--color-components-main-nav-nav-button-bg-active: var(--color-components-main-nav-nav-button-bg-active);
--color-components-main-nav-nav-button-border: var(--color-components-main-nav-nav-button-border);
--color-components-main-nav-nav-button-bg-hover: var(--color-components-main-nav-nav-button-bg-hover);
--color-components-main-nav-nav-user-border: var(--color-components-main-nav-nav-user-border);
--color-components-slider-knob: var(--color-components-slider-knob);
--color-components-slider-knob-hover: var(--color-components-slider-knob-hover);
--color-components-slider-knob-disabled: var(--color-components-slider-knob-disabled);
--color-components-slider-range: var(--color-components-slider-range);
--color-components-slider-track: var(--color-components-slider-track);
--color-components-slider-knob-border-hover: var(--color-components-slider-knob-border-hover);
--color-components-slider-knob-border: var(--color-components-slider-knob-border);
--color-components-segmented-control-item-active-bg: var(--color-components-segmented-control-item-active-bg);
--color-components-segmented-control-item-active-border: var(--color-components-segmented-control-item-active-border);
--color-components-segmented-control-bg-normal: var(--color-components-segmented-control-bg-normal);
--color-components-segmented-control-item-active-accent-bg: var(--color-components-segmented-control-item-active-accent-bg);
--color-components-segmented-control-item-active-accent-border: var(--color-components-segmented-control-item-active-accent-border);
--color-components-option-card-option-bg: var(--color-components-option-card-option-bg);
--color-components-option-card-option-selected-bg: var(--color-components-option-card-option-selected-bg);
--color-components-option-card-option-selected-border: var(--color-components-option-card-option-selected-border);
--color-components-option-card-option-border: var(--color-components-option-card-option-border);
--color-components-option-card-option-bg-hover: var(--color-components-option-card-option-bg-hover);
--color-components-option-card-option-border-hover: var(--color-components-option-card-option-border-hover);
--color-components-tab-active: var(--color-components-tab-active);
--color-components-badge-white-to-dark: var(--color-components-badge-white-to-dark);
--color-components-badge-status-light-success-bg: var(--color-components-badge-status-light-success-bg);
--color-components-badge-status-light-success-border-inner: var(--color-components-badge-status-light-success-border-inner);
--color-components-badge-status-light-success-halo: var(--color-components-badge-status-light-success-halo);
--color-components-badge-status-light-border-outer: var(--color-components-badge-status-light-border-outer);
--color-components-badge-status-light-high-light: var(--color-components-badge-status-light-high-light);
--color-components-badge-status-light-warning-bg: var(--color-components-badge-status-light-warning-bg);
--color-components-badge-status-light-warning-border-inner: var(--color-components-badge-status-light-warning-border-inner);
--color-components-badge-status-light-warning-halo: var(--color-components-badge-status-light-warning-halo);
--color-components-badge-status-light-error-bg: var(--color-components-badge-status-light-error-bg);
--color-components-badge-status-light-error-border-inner: var(--color-components-badge-status-light-error-border-inner);
--color-components-badge-status-light-error-halo: var(--color-components-badge-status-light-error-halo);
--color-components-badge-status-light-normal-bg: var(--color-components-badge-status-light-normal-bg);
--color-components-badge-status-light-normal-border-inner: var(--color-components-badge-status-light-normal-border-inner);
--color-components-badge-status-light-normal-halo: var(--color-components-badge-status-light-normal-halo);
--color-components-badge-status-light-disabled-bg: var(--color-components-badge-status-light-disabled-bg);
--color-components-badge-status-light-disabled-border-inner: var(--color-components-badge-status-light-disabled-border-inner);
--color-components-badge-status-light-disabled-halo: var(--color-components-badge-status-light-disabled-halo);
--color-components-badge-bg-green-soft: var(--color-components-badge-bg-green-soft);
--color-components-badge-bg-orange-soft: var(--color-components-badge-bg-orange-soft);
--color-components-badge-bg-red-soft: var(--color-components-badge-bg-red-soft);
--color-components-badge-bg-blue-light-soft: var(--color-components-badge-bg-blue-light-soft);
--color-components-badge-bg-gray-soft: var(--color-components-badge-bg-gray-soft);
--color-components-badge-bg-dimm: var(--color-components-badge-bg-dimm);
--color-components-chart-line: var(--color-components-chart-line);
--color-components-chart-area-1: var(--color-components-chart-area-1);
--color-components-chart-area-2: var(--color-components-chart-area-2);
--color-components-chart-current-1: var(--color-components-chart-current-1);
--color-components-chart-current-2: var(--color-components-chart-current-2);
--color-components-chart-bg: var(--color-components-chart-bg);
--color-components-actionbar-bg: var(--color-components-actionbar-bg);
--color-components-actionbar-border: var(--color-components-actionbar-border);
--color-components-actionbar-bg-accent: var(--color-components-actionbar-bg-accent);
--color-components-actionbar-border-accent: var(--color-components-actionbar-border-accent);
--color-components-dropzone-bg-alt: var(--color-components-dropzone-bg-alt);
--color-components-dropzone-bg: var(--color-components-dropzone-bg);
--color-components-dropzone-bg-accent: var(--color-components-dropzone-bg-accent);
--color-components-dropzone-border: var(--color-components-dropzone-border);
--color-components-dropzone-border-alt: var(--color-components-dropzone-border-alt);
--color-components-dropzone-border-accent: var(--color-components-dropzone-border-accent);
--color-components-progress-brand-progress: var(--color-components-progress-brand-progress);
--color-components-progress-brand-border: var(--color-components-progress-brand-border);
--color-components-progress-brand-bg: var(--color-components-progress-brand-bg);
--color-components-progress-white-progress: var(--color-components-progress-white-progress);
--color-components-progress-white-border: var(--color-components-progress-white-border);
--color-components-progress-white-bg: var(--color-components-progress-white-bg);
--color-components-progress-gray-progress: var(--color-components-progress-gray-progress);
--color-components-progress-gray-border: var(--color-components-progress-gray-border);
--color-components-progress-gray-bg: var(--color-components-progress-gray-bg);
--color-components-progress-warning-progress: var(--color-components-progress-warning-progress);
--color-components-progress-warning-border: var(--color-components-progress-warning-border);
--color-components-progress-warning-bg: var(--color-components-progress-warning-bg);
--color-components-progress-error-progress: var(--color-components-progress-error-progress);
--color-components-progress-error-border: var(--color-components-progress-error-border);
--color-components-progress-error-bg: var(--color-components-progress-error-bg);
--color-components-chat-input-audio-bg: var(--color-components-chat-input-audio-bg);
--color-components-chat-input-audio-wave-default: var(--color-components-chat-input-audio-wave-default);
--color-components-chat-input-bg-mask-1: var(--color-components-chat-input-bg-mask-1);
--color-components-chat-input-bg-mask-2: var(--color-components-chat-input-bg-mask-2);
--color-components-chat-input-border: var(--color-components-chat-input-border);
--color-components-chat-input-audio-wave-active: var(--color-components-chat-input-audio-wave-active);
--color-components-chat-input-audio-bg-alt: var(--color-components-chat-input-audio-bg-alt);
--color-components-avatar-shape-fill-stop-0: var(--color-components-avatar-shape-fill-stop-0);
--color-components-avatar-shape-fill-stop-100: var(--color-components-avatar-shape-fill-stop-100);
--color-components-avatar-bg-mask-stop-0: var(--color-components-avatar-bg-mask-stop-0);
--color-components-avatar-bg-mask-stop-100: var(--color-components-avatar-bg-mask-stop-100);
--color-components-avatar-default-avatar-bg: var(--color-components-avatar-default-avatar-bg);
--color-components-avatar-mask-darkmode-dimmed: var(--color-components-avatar-mask-darkmode-dimmed);
--color-components-label-gray: var(--color-components-label-gray);
--color-components-premium-badge-blue-bg-stop-0: var(--color-components-premium-badge-blue-bg-stop-0);
--color-components-premium-badge-blue-bg-stop-100: var(--color-components-premium-badge-blue-bg-stop-100);
--color-components-premium-badge-blue-stroke-stop-0: var(--color-components-premium-badge-blue-stroke-stop-0);
--color-components-premium-badge-blue-stroke-stop-100: var(--color-components-premium-badge-blue-stroke-stop-100);
--color-components-premium-badge-blue-text-stop-0: var(--color-components-premium-badge-blue-text-stop-0);
--color-components-premium-badge-blue-text-stop-100: var(--color-components-premium-badge-blue-text-stop-100);
--color-components-premium-badge-blue-glow: var(--color-components-premium-badge-blue-glow);
--color-components-premium-badge-blue-bg-stop-0-hover: var(--color-components-premium-badge-blue-bg-stop-0-hover);
--color-components-premium-badge-blue-bg-stop-100-hover: var(--color-components-premium-badge-blue-bg-stop-100-hover);
--color-components-premium-badge-blue-glow-hover: var(--color-components-premium-badge-blue-glow-hover);
--color-components-premium-badge-blue-stroke-stop-0-hover: var(--color-components-premium-badge-blue-stroke-stop-0-hover);
--color-components-premium-badge-blue-stroke-stop-100-hover: var(--color-components-premium-badge-blue-stroke-stop-100-hover);
--color-components-premium-badge-highlight-stop-0: var(--color-components-premium-badge-highlight-stop-0);
--color-components-premium-badge-highlight-stop-100: var(--color-components-premium-badge-highlight-stop-100);
--color-components-premium-badge-indigo-bg-stop-0: var(--color-components-premium-badge-indigo-bg-stop-0);
--color-components-premium-badge-indigo-bg-stop-100: var(--color-components-premium-badge-indigo-bg-stop-100);
--color-components-premium-badge-indigo-stroke-stop-0: var(--color-components-premium-badge-indigo-stroke-stop-0);
--color-components-premium-badge-indigo-stroke-stop-100: var(--color-components-premium-badge-indigo-stroke-stop-100);
--color-components-premium-badge-indigo-text-stop-0: var(--color-components-premium-badge-indigo-text-stop-0);
--color-components-premium-badge-indigo-text-stop-100: var(--color-components-premium-badge-indigo-text-stop-100);
--color-components-premium-badge-indigo-glow: var(--color-components-premium-badge-indigo-glow);
--color-components-premium-badge-indigo-glow-hover: var(--color-components-premium-badge-indigo-glow-hover);
--color-components-premium-badge-indigo-bg-stop-0-hover: var(--color-components-premium-badge-indigo-bg-stop-0-hover);
--color-components-premium-badge-indigo-bg-stop-100-hover: var(--color-components-premium-badge-indigo-bg-stop-100-hover);
--color-components-premium-badge-indigo-stroke-stop-0-hover: var(--color-components-premium-badge-indigo-stroke-stop-0-hover);
--color-components-premium-badge-indigo-stroke-stop-100-hover: var(--color-components-premium-badge-indigo-stroke-stop-100-hover);
--color-components-premium-badge-grey-bg-stop-0: var(--color-components-premium-badge-grey-bg-stop-0);
--color-components-premium-badge-grey-bg-stop-100: var(--color-components-premium-badge-grey-bg-stop-100);
--color-components-premium-badge-grey-stroke-stop-0: var(--color-components-premium-badge-grey-stroke-stop-0);
--color-components-premium-badge-grey-stroke-stop-100: var(--color-components-premium-badge-grey-stroke-stop-100);
--color-components-premium-badge-grey-text-stop-0: var(--color-components-premium-badge-grey-text-stop-0);
--color-components-premium-badge-grey-text-stop-100: var(--color-components-premium-badge-grey-text-stop-100);
--color-components-premium-badge-grey-glow: var(--color-components-premium-badge-grey-glow);
--color-components-premium-badge-grey-glow-hover: var(--color-components-premium-badge-grey-glow-hover);
--color-components-premium-badge-grey-bg-stop-0-hover: var(--color-components-premium-badge-grey-bg-stop-0-hover);
--color-components-premium-badge-grey-bg-stop-100-hover: var(--color-components-premium-badge-grey-bg-stop-100-hover);
--color-components-premium-badge-grey-stroke-stop-0-hover: var(--color-components-premium-badge-grey-stroke-stop-0-hover);
--color-components-premium-badge-grey-stroke-stop-100-hover: var(--color-components-premium-badge-grey-stroke-stop-100-hover);
--color-components-premium-badge-orange-bg-stop-0: var(--color-components-premium-badge-orange-bg-stop-0);
--color-components-premium-badge-orange-bg-stop-100: var(--color-components-premium-badge-orange-bg-stop-100);
--color-components-premium-badge-orange-stroke-stop-0: var(--color-components-premium-badge-orange-stroke-stop-0);
--color-components-premium-badge-orange-stroke-stop-100: var(--color-components-premium-badge-orange-stroke-stop-100);
--color-components-premium-badge-orange-text-stop-0: var(--color-components-premium-badge-orange-text-stop-0);
--color-components-premium-badge-orange-text-stop-100: var(--color-components-premium-badge-orange-text-stop-100);
--color-components-premium-badge-orange-glow: var(--color-components-premium-badge-orange-glow);
--color-components-premium-badge-orange-glow-hover: var(--color-components-premium-badge-orange-glow-hover);
--color-components-premium-badge-orange-bg-stop-0-hover: var(--color-components-premium-badge-orange-bg-stop-0-hover);
--color-components-premium-badge-orange-bg-stop-100-hover: var(--color-components-premium-badge-orange-bg-stop-100-hover);
--color-components-premium-badge-orange-stroke-stop-0-hover: var(--color-components-premium-badge-orange-stroke-stop-0-hover);
--color-components-premium-badge-orange-stroke-stop-100-hover: var(--color-components-premium-badge-orange-stroke-stop-100-hover);
--color-components-progress-bar-bg: var(--color-components-progress-bar-bg);
--color-components-progress-bar-progress: var(--color-components-progress-bar-progress);
--color-components-progress-bar-border: var(--color-components-progress-bar-border);
--color-components-progress-bar-progress-solid: var(--color-components-progress-bar-progress-solid);
--color-components-progress-bar-progress-highlight: var(--color-components-progress-bar-progress-highlight);
--color-components-icon-bg-red-solid: var(--color-components-icon-bg-red-solid);
--color-components-icon-bg-rose-solid: var(--color-components-icon-bg-rose-solid);
--color-components-icon-bg-pink-solid: var(--color-components-icon-bg-pink-solid);
--color-components-icon-bg-orange-dark-solid: var(--color-components-icon-bg-orange-dark-solid);
--color-components-icon-bg-yellow-solid: var(--color-components-icon-bg-yellow-solid);
--color-components-icon-bg-green-solid: var(--color-components-icon-bg-green-solid);
--color-components-icon-bg-teal-solid: var(--color-components-icon-bg-teal-solid);
--color-components-icon-bg-blue-light-solid: var(--color-components-icon-bg-blue-light-solid);
--color-components-icon-bg-blue-solid: var(--color-components-icon-bg-blue-solid);
--color-components-icon-bg-indigo-solid: var(--color-components-icon-bg-indigo-solid);
--color-components-icon-bg-violet-solid: var(--color-components-icon-bg-violet-solid);
--color-components-icon-bg-midnight-solid: var(--color-components-icon-bg-midnight-solid);
--color-components-icon-bg-rose-soft: var(--color-components-icon-bg-rose-soft);
--color-components-icon-bg-pink-soft: var(--color-components-icon-bg-pink-soft);
--color-components-icon-bg-orange-dark-soft: var(--color-components-icon-bg-orange-dark-soft);
--color-components-icon-bg-yellow-soft: var(--color-components-icon-bg-yellow-soft);
--color-components-icon-bg-green-soft: var(--color-components-icon-bg-green-soft);
--color-components-icon-bg-teal-soft: var(--color-components-icon-bg-teal-soft);
--color-components-icon-bg-blue-light-soft: var(--color-components-icon-bg-blue-light-soft);
--color-components-icon-bg-blue-soft: var(--color-components-icon-bg-blue-soft);
--color-components-icon-bg-indigo-soft: var(--color-components-icon-bg-indigo-soft);
--color-components-icon-bg-violet-soft: var(--color-components-icon-bg-violet-soft);
--color-components-icon-bg-midnight-soft: var(--color-components-icon-bg-midnight-soft);
--color-components-icon-bg-red-soft: var(--color-components-icon-bg-red-soft);
--color-components-icon-bg-orange-solid: var(--color-components-icon-bg-orange-solid);
--color-components-icon-bg-orange-soft: var(--color-components-icon-bg-orange-soft);
--color-text-primary: var(--color-text-primary);
--color-text-secondary: var(--color-text-secondary);
--color-text-tertiary: var(--color-text-tertiary);
--color-text-quaternary: var(--color-text-quaternary);
--color-text-destructive: var(--color-text-destructive);
--color-text-success: var(--color-text-success);
--color-text-warning: var(--color-text-warning);
--color-text-destructive-secondary: var(--color-text-destructive-secondary);
--color-text-success-secondary: var(--color-text-success-secondary);
--color-text-warning-secondary: var(--color-text-warning-secondary);
--color-text-accent: var(--color-text-accent);
--color-text-primary-on-surface: var(--color-text-primary-on-surface);
--color-text-placeholder: var(--color-text-placeholder);
--color-text-disabled: var(--color-text-disabled);
--color-text-accent-secondary: var(--color-text-accent-secondary);
--color-text-accent-light-mode-only: var(--color-text-accent-light-mode-only);
--color-text-text-selected: var(--color-text-text-selected);
--color-text-secondary-on-surface: var(--color-text-secondary-on-surface);
--color-text-logo-text: var(--color-text-logo-text);
--color-text-empty-state-icon: var(--color-text-empty-state-icon);
--color-text-inverted: var(--color-text-inverted);
--color-text-inverted-dimmed: var(--color-text-inverted-dimmed);
--color-background-body: var(--color-background-body);
--color-background-default-subtle: var(--color-background-default-subtle);
--color-background-neutral-subtle: var(--color-background-neutral-subtle);
--color-background-sidenav-bg: var(--color-background-sidenav-bg);
--color-background-default: var(--color-background-default);
--color-background-soft: var(--color-background-soft);
--color-background-gradient-bg-fill-chat-bg-1: var(--color-background-gradient-bg-fill-chat-bg-1);
--color-background-gradient-bg-fill-chat-bg-2: var(--color-background-gradient-bg-fill-chat-bg-2);
--color-background-gradient-bg-fill-chat-bubble-bg-1: var(--color-background-gradient-bg-fill-chat-bubble-bg-1);
--color-background-gradient-bg-fill-chat-bubble-bg-2: var(--color-background-gradient-bg-fill-chat-bubble-bg-2);
--color-background-gradient-bg-fill-debug-bg-1: var(--color-background-gradient-bg-fill-debug-bg-1);
--color-background-gradient-bg-fill-debug-bg-2: var(--color-background-gradient-bg-fill-debug-bg-2);
--color-background-gradient-mask-gray: var(--color-background-gradient-mask-gray);
--color-background-gradient-mask-transparent: var(--color-background-gradient-mask-transparent);
--color-background-gradient-mask-input-clear-2: var(--color-background-gradient-mask-input-clear-2);
--color-background-gradient-mask-input-clear-1: var(--color-background-gradient-mask-input-clear-1);
--color-background-gradient-mask-transparent-dark: var(--color-background-gradient-mask-transparent-dark);
--color-background-gradient-mask-side-panel-2: var(--color-background-gradient-mask-side-panel-2);
--color-background-gradient-mask-side-panel-1: var(--color-background-gradient-mask-side-panel-1);
--color-background-default-burn: var(--color-background-default-burn);
--color-background-overlay-fullscreen: var(--color-background-overlay-fullscreen);
--color-background-default-lighter: var(--color-background-default-lighter);
--color-background-section: var(--color-background-section);
--color-background-interaction-from-bg-1: var(--color-background-interaction-from-bg-1);
--color-background-interaction-from-bg-2: var(--color-background-interaction-from-bg-2);
--color-background-section-burn: var(--color-background-section-burn);
--color-background-default-dodge: var(--color-background-default-dodge);
--color-background-overlay: var(--color-background-overlay);
--color-background-default-dimmed: var(--color-background-default-dimmed);
--color-background-default-hover: var(--color-background-default-hover);
--color-background-overlay-alt: var(--color-background-overlay-alt);
--color-background-surface-white: var(--color-background-surface-white);
--color-background-overlay-destructive: var(--color-background-overlay-destructive);
--color-background-overlay-backdrop: var(--color-background-overlay-backdrop);
--color-background-body-transparent: var(--color-background-body-transparent);
--color-background-section-burn-inverted: var(--color-background-section-burn-inverted);
--color-shadow-shadow-1: var(--color-shadow-shadow-1);
--color-shadow-shadow-3: var(--color-shadow-shadow-3);
--color-shadow-shadow-4: var(--color-shadow-shadow-4);
--color-shadow-shadow-5: var(--color-shadow-shadow-5);
--color-shadow-shadow-6: var(--color-shadow-shadow-6);
--color-shadow-shadow-7: var(--color-shadow-shadow-7);
--color-shadow-shadow-8: var(--color-shadow-shadow-8);
--color-shadow-shadow-9: var(--color-shadow-shadow-9);
--color-shadow-shadow-2: var(--color-shadow-shadow-2);
--color-shadow-shadow-10: var(--color-shadow-shadow-10);
--color-workflow-block-border: var(--color-workflow-block-border);
--color-workflow-block-parma-bg: var(--color-workflow-block-parma-bg);
--color-workflow-block-bg: var(--color-workflow-block-bg);
--color-workflow-block-bg-transparent: var(--color-workflow-block-bg-transparent);
--color-workflow-block-border-highlight: var(--color-workflow-block-border-highlight);
--color-workflow-block-wrapper-bg-1: var(--color-workflow-block-wrapper-bg-1);
--color-workflow-block-wrapper-bg-2: var(--color-workflow-block-wrapper-bg-2);
--color-workflow-canvas-workflow-dot-color: var(--color-workflow-canvas-workflow-dot-color);
--color-workflow-canvas-workflow-bg: var(--color-workflow-canvas-workflow-bg);
--color-workflow-canvas-workflow-top-bar-1: var(--color-workflow-canvas-workflow-top-bar-1);
--color-workflow-canvas-workflow-top-bar-2: var(--color-workflow-canvas-workflow-top-bar-2);
--color-workflow-canvas-canvas-overlay: var(--color-workflow-canvas-canvas-overlay);
--color-workflow-link-line-active: var(--color-workflow-link-line-active);
--color-workflow-link-line-normal: var(--color-workflow-link-line-normal);
--color-workflow-link-line-handle: var(--color-workflow-link-line-handle);
--color-workflow-link-line-normal-transparent: var(--color-workflow-link-line-normal-transparent);
--color-workflow-link-line-failure-active: var(--color-workflow-link-line-failure-active);
--color-workflow-link-line-failure-handle: var(--color-workflow-link-line-failure-handle);
--color-workflow-link-line-failure-button-bg: var(--color-workflow-link-line-failure-button-bg);
--color-workflow-link-line-failure-button-hover: var(--color-workflow-link-line-failure-button-hover);
--color-workflow-link-line-success-active: var(--color-workflow-link-line-success-active);
--color-workflow-link-line-success-handle: var(--color-workflow-link-line-success-handle);
--color-workflow-link-line-error-active: var(--color-workflow-link-line-error-active);
--color-workflow-link-line-error-handle: var(--color-workflow-link-line-error-handle);
--color-workflow-minimap-bg: var(--color-workflow-minimap-bg);
--color-workflow-minimap-block: var(--color-workflow-minimap-block);
--color-workflow-display-success-bg: var(--color-workflow-display-success-bg);
--color-workflow-display-success-border-1: var(--color-workflow-display-success-border-1);
--color-workflow-display-success-border-2: var(--color-workflow-display-success-border-2);
--color-workflow-display-success-vignette-color: var(--color-workflow-display-success-vignette-color);
--color-workflow-display-success-bg-line-pattern: var(--color-workflow-display-success-bg-line-pattern);
--color-workflow-display-glass-1: var(--color-workflow-display-glass-1);
--color-workflow-display-glass-2: var(--color-workflow-display-glass-2);
--color-workflow-display-vignette-dark: var(--color-workflow-display-vignette-dark);
--color-workflow-display-highlight: var(--color-workflow-display-highlight);
--color-workflow-display-outline: var(--color-workflow-display-outline);
--color-workflow-display-error-bg: var(--color-workflow-display-error-bg);
--color-workflow-display-error-bg-line-pattern: var(--color-workflow-display-error-bg-line-pattern);
--color-workflow-display-error-border-1: var(--color-workflow-display-error-border-1);
--color-workflow-display-error-border-2: var(--color-workflow-display-error-border-2);
--color-workflow-display-error-vignette-color: var(--color-workflow-display-error-vignette-color);
--color-workflow-display-warning-bg: var(--color-workflow-display-warning-bg);
--color-workflow-display-warning-bg-line-pattern: var(--color-workflow-display-warning-bg-line-pattern);
--color-workflow-display-warning-border-1: var(--color-workflow-display-warning-border-1);
--color-workflow-display-warning-border-2: var(--color-workflow-display-warning-border-2);
--color-workflow-display-warning-vignette-color: var(--color-workflow-display-warning-vignette-color);
--color-workflow-display-normal-bg: var(--color-workflow-display-normal-bg);
--color-workflow-display-normal-bg-line-pattern: var(--color-workflow-display-normal-bg-line-pattern);
--color-workflow-display-normal-border-1: var(--color-workflow-display-normal-border-1);
--color-workflow-display-normal-border-2: var(--color-workflow-display-normal-border-2);
--color-workflow-display-normal-vignette-color: var(--color-workflow-display-normal-vignette-color);
--color-workflow-display-disabled-bg: var(--color-workflow-display-disabled-bg);
--color-workflow-display-disabled-bg-line-pattern: var(--color-workflow-display-disabled-bg-line-pattern);
--color-workflow-display-disabled-border-1: var(--color-workflow-display-disabled-border-1);
--color-workflow-display-disabled-border-2: var(--color-workflow-display-disabled-border-2);
--color-workflow-display-disabled-vignette-color: var(--color-workflow-display-disabled-vignette-color);
--color-workflow-display-disabled-outline: var(--color-workflow-display-disabled-outline);
--color-workflow-workflow-progress-bg-1: var(--color-workflow-workflow-progress-bg-1);
--color-workflow-workflow-progress-bg-2: var(--color-workflow-workflow-progress-bg-2);
--color-divider-subtle: var(--color-divider-subtle);
--color-divider-regular: var(--color-divider-regular);
--color-divider-deep: var(--color-divider-deep);
--color-divider-burn: var(--color-divider-burn);
--color-divider-intense: var(--color-divider-intense);
--color-divider-solid: var(--color-divider-solid);
--color-divider-solid-alt: var(--color-divider-solid-alt);
--color-divider-accent: var(--color-divider-accent);
--color-state-base-hover: var(--color-state-base-hover);
--color-state-base-active: var(--color-state-base-active);
--color-state-base-hover-alt: var(--color-state-base-hover-alt);
--color-state-base-handle: var(--color-state-base-handle);
--color-state-base-handle-hover: var(--color-state-base-handle-hover);
--color-state-base-hover-subtle: var(--color-state-base-hover-subtle);
--color-state-accent-hover: var(--color-state-accent-hover);
--color-state-accent-active: var(--color-state-accent-active);
--color-state-accent-hover-alt: var(--color-state-accent-hover-alt);
--color-state-accent-solid: var(--color-state-accent-solid);
--color-state-accent-active-alt: var(--color-state-accent-active-alt);
--color-state-destructive-hover: var(--color-state-destructive-hover);
--color-state-destructive-hover-alt: var(--color-state-destructive-hover-alt);
--color-state-destructive-active: var(--color-state-destructive-active);
--color-state-destructive-solid: var(--color-state-destructive-solid);
--color-state-destructive-border: var(--color-state-destructive-border);
--color-state-destructive-hover-transparent: var(--color-state-destructive-hover-transparent);
--color-state-success-hover: var(--color-state-success-hover);
--color-state-success-hover-alt: var(--color-state-success-hover-alt);
--color-state-success-active: var(--color-state-success-active);
--color-state-success-solid: var(--color-state-success-solid);
--color-state-warning-hover: var(--color-state-warning-hover);
--color-state-warning-hover-alt: var(--color-state-warning-hover-alt);
--color-state-warning-active: var(--color-state-warning-active);
--color-state-warning-solid: var(--color-state-warning-solid);
--color-state-warning-hover-transparent: var(--color-state-warning-hover-transparent);
--color-effects-highlight: var(--color-effects-highlight);
--color-effects-highlight-lightmode-off: var(--color-effects-highlight-lightmode-off);
--color-effects-image-frame: var(--color-effects-image-frame);
--color-effects-icon-border: var(--color-effects-icon-border);
--color-util-colors-orange-dark-orange-dark-50: var(--color-util-colors-orange-dark-orange-dark-50);
--color-util-colors-orange-dark-orange-dark-100: var(--color-util-colors-orange-dark-orange-dark-100);
--color-util-colors-orange-dark-orange-dark-200: var(--color-util-colors-orange-dark-orange-dark-200);
--color-util-colors-orange-dark-orange-dark-300: var(--color-util-colors-orange-dark-orange-dark-300);
--color-util-colors-orange-dark-orange-dark-400: var(--color-util-colors-orange-dark-orange-dark-400);
--color-util-colors-orange-dark-orange-dark-500: var(--color-util-colors-orange-dark-orange-dark-500);
--color-util-colors-orange-dark-orange-dark-600: var(--color-util-colors-orange-dark-orange-dark-600);
--color-util-colors-orange-dark-orange-dark-700: var(--color-util-colors-orange-dark-orange-dark-700);
--color-util-colors-orange-orange-50: var(--color-util-colors-orange-orange-50);
--color-util-colors-orange-orange-100: var(--color-util-colors-orange-orange-100);
--color-util-colors-orange-orange-200: var(--color-util-colors-orange-orange-200);
--color-util-colors-orange-orange-300: var(--color-util-colors-orange-orange-300);
--color-util-colors-orange-orange-400: var(--color-util-colors-orange-orange-400);
--color-util-colors-orange-orange-500: var(--color-util-colors-orange-orange-500);
--color-util-colors-orange-orange-600: var(--color-util-colors-orange-orange-600);
--color-util-colors-orange-orange-700: var(--color-util-colors-orange-orange-700);
--color-util-colors-orange-orange-100-transparent: var(--color-util-colors-orange-orange-100-transparent);
--color-util-colors-pink-pink-50: var(--color-util-colors-pink-pink-50);
--color-util-colors-pink-pink-100: var(--color-util-colors-pink-pink-100);
--color-util-colors-pink-pink-200: var(--color-util-colors-pink-pink-200);
--color-util-colors-pink-pink-300: var(--color-util-colors-pink-pink-300);
--color-util-colors-pink-pink-400: var(--color-util-colors-pink-pink-400);
--color-util-colors-pink-pink-500: var(--color-util-colors-pink-pink-500);
--color-util-colors-pink-pink-600: var(--color-util-colors-pink-pink-600);
--color-util-colors-pink-pink-700: var(--color-util-colors-pink-pink-700);
--color-util-colors-fuchsia-fuchsia-50: var(--color-util-colors-fuchsia-fuchsia-50);
--color-util-colors-fuchsia-fuchsia-100: var(--color-util-colors-fuchsia-fuchsia-100);
--color-util-colors-fuchsia-fuchsia-200: var(--color-util-colors-fuchsia-fuchsia-200);
--color-util-colors-fuchsia-fuchsia-300: var(--color-util-colors-fuchsia-fuchsia-300);
--color-util-colors-fuchsia-fuchsia-400: var(--color-util-colors-fuchsia-fuchsia-400);
--color-util-colors-fuchsia-fuchsia-500: var(--color-util-colors-fuchsia-fuchsia-500);
--color-util-colors-fuchsia-fuchsia-600: var(--color-util-colors-fuchsia-fuchsia-600);
--color-util-colors-fuchsia-fuchsia-700: var(--color-util-colors-fuchsia-fuchsia-700);
--color-util-colors-purple-purple-50: var(--color-util-colors-purple-purple-50);
--color-util-colors-purple-purple-100: var(--color-util-colors-purple-purple-100);
--color-util-colors-purple-purple-200: var(--color-util-colors-purple-purple-200);
--color-util-colors-purple-purple-300: var(--color-util-colors-purple-purple-300);
--color-util-colors-purple-purple-400: var(--color-util-colors-purple-purple-400);
--color-util-colors-purple-purple-500: var(--color-util-colors-purple-purple-500);
--color-util-colors-purple-purple-600: var(--color-util-colors-purple-purple-600);
--color-util-colors-purple-purple-700: var(--color-util-colors-purple-purple-700);
--color-util-colors-indigo-indigo-50: var(--color-util-colors-indigo-indigo-50);
--color-util-colors-indigo-indigo-100: var(--color-util-colors-indigo-indigo-100);
--color-util-colors-indigo-indigo-200: var(--color-util-colors-indigo-indigo-200);
--color-util-colors-indigo-indigo-300: var(--color-util-colors-indigo-indigo-300);
--color-util-colors-indigo-indigo-400: var(--color-util-colors-indigo-indigo-400);
--color-util-colors-indigo-indigo-500: var(--color-util-colors-indigo-indigo-500);
--color-util-colors-indigo-indigo-600: var(--color-util-colors-indigo-indigo-600);
--color-util-colors-indigo-indigo-700: var(--color-util-colors-indigo-indigo-700);
--color-util-colors-blue-blue-50: var(--color-util-colors-blue-blue-50);
--color-util-colors-blue-blue-100: var(--color-util-colors-blue-blue-100);
--color-util-colors-blue-blue-200: var(--color-util-colors-blue-blue-200);
--color-util-colors-blue-blue-300: var(--color-util-colors-blue-blue-300);
--color-util-colors-blue-blue-400: var(--color-util-colors-blue-blue-400);
--color-util-colors-blue-blue-500: var(--color-util-colors-blue-blue-500);
--color-util-colors-blue-blue-600: var(--color-util-colors-blue-blue-600);
--color-util-colors-blue-blue-700: var(--color-util-colors-blue-blue-700);
--color-util-colors-blue-light-blue-light-50: var(--color-util-colors-blue-light-blue-light-50);
--color-util-colors-blue-light-blue-light-100: var(--color-util-colors-blue-light-blue-light-100);
--color-util-colors-blue-light-blue-light-200: var(--color-util-colors-blue-light-blue-light-200);
--color-util-colors-blue-light-blue-light-300: var(--color-util-colors-blue-light-blue-light-300);
--color-util-colors-blue-light-blue-light-400: var(--color-util-colors-blue-light-blue-light-400);
--color-util-colors-blue-light-blue-light-500: var(--color-util-colors-blue-light-blue-light-500);
--color-util-colors-blue-light-blue-light-600: var(--color-util-colors-blue-light-blue-light-600);
--color-util-colors-blue-light-blue-light-700: var(--color-util-colors-blue-light-blue-light-700);
--color-util-colors-gray-blue-gray-blue-50: var(--color-util-colors-gray-blue-gray-blue-50);
--color-util-colors-gray-blue-gray-blue-100: var(--color-util-colors-gray-blue-gray-blue-100);
--color-util-colors-gray-blue-gray-blue-200: var(--color-util-colors-gray-blue-gray-blue-200);
--color-util-colors-gray-blue-gray-blue-300: var(--color-util-colors-gray-blue-gray-blue-300);
--color-util-colors-gray-blue-gray-blue-400: var(--color-util-colors-gray-blue-gray-blue-400);
--color-util-colors-gray-blue-gray-blue-500: var(--color-util-colors-gray-blue-gray-blue-500);
--color-util-colors-gray-blue-gray-blue-600: var(--color-util-colors-gray-blue-gray-blue-600);
--color-util-colors-gray-blue-gray-blue-700: var(--color-util-colors-gray-blue-gray-blue-700);
--color-util-colors-blue-brand-blue-brand-50: var(--color-util-colors-blue-brand-blue-brand-50);
--color-util-colors-blue-brand-blue-brand-100: var(--color-util-colors-blue-brand-blue-brand-100);
--color-util-colors-blue-brand-blue-brand-200: var(--color-util-colors-blue-brand-blue-brand-200);
--color-util-colors-blue-brand-blue-brand-300: var(--color-util-colors-blue-brand-blue-brand-300);
--color-util-colors-blue-brand-blue-brand-400: var(--color-util-colors-blue-brand-blue-brand-400);
--color-util-colors-blue-brand-blue-brand-500: var(--color-util-colors-blue-brand-blue-brand-500);
--color-util-colors-blue-brand-blue-brand-600: var(--color-util-colors-blue-brand-blue-brand-600);
--color-util-colors-blue-brand-blue-brand-700: var(--color-util-colors-blue-brand-blue-brand-700);
--color-util-colors-red-red-50: var(--color-util-colors-red-red-50);
--color-util-colors-red-red-100: var(--color-util-colors-red-red-100);
--color-util-colors-red-red-200: var(--color-util-colors-red-red-200);
--color-util-colors-red-red-300: var(--color-util-colors-red-red-300);
--color-util-colors-red-red-400: var(--color-util-colors-red-red-400);
--color-util-colors-red-red-500: var(--color-util-colors-red-red-500);
--color-util-colors-red-red-600: var(--color-util-colors-red-red-600);
--color-util-colors-red-red-700: var(--color-util-colors-red-red-700);
--color-util-colors-green-green-50: var(--color-util-colors-green-green-50);
--color-util-colors-green-green-100: var(--color-util-colors-green-green-100);
--color-util-colors-green-green-200: var(--color-util-colors-green-green-200);
--color-util-colors-green-green-300: var(--color-util-colors-green-green-300);
--color-util-colors-green-green-400: var(--color-util-colors-green-green-400);
--color-util-colors-green-green-500: var(--color-util-colors-green-green-500);
--color-util-colors-green-green-600: var(--color-util-colors-green-green-600);
--color-util-colors-green-green-700: var(--color-util-colors-green-green-700);
--color-util-colors-warning-warning-50: var(--color-util-colors-warning-warning-50);
--color-util-colors-warning-warning-100: var(--color-util-colors-warning-warning-100);
--color-util-colors-warning-warning-200: var(--color-util-colors-warning-warning-200);
--color-util-colors-warning-warning-300: var(--color-util-colors-warning-warning-300);
--color-util-colors-warning-warning-400: var(--color-util-colors-warning-warning-400);
--color-util-colors-warning-warning-500: var(--color-util-colors-warning-warning-500);
--color-util-colors-warning-warning-600: var(--color-util-colors-warning-warning-600);
--color-util-colors-warning-warning-700: var(--color-util-colors-warning-warning-700);
--color-util-colors-yellow-yellow-50: var(--color-util-colors-yellow-yellow-50);
--color-util-colors-yellow-yellow-100: var(--color-util-colors-yellow-yellow-100);
--color-util-colors-yellow-yellow-200: var(--color-util-colors-yellow-yellow-200);
--color-util-colors-yellow-yellow-300: var(--color-util-colors-yellow-yellow-300);
--color-util-colors-yellow-yellow-400: var(--color-util-colors-yellow-yellow-400);
--color-util-colors-yellow-yellow-500: var(--color-util-colors-yellow-yellow-500);
--color-util-colors-yellow-yellow-600: var(--color-util-colors-yellow-yellow-600);
--color-util-colors-yellow-yellow-700: var(--color-util-colors-yellow-yellow-700);
--color-util-colors-teal-teal-50: var(--color-util-colors-teal-teal-50);
--color-util-colors-teal-teal-100: var(--color-util-colors-teal-teal-100);
--color-util-colors-teal-teal-200: var(--color-util-colors-teal-teal-200);
--color-util-colors-teal-teal-300: var(--color-util-colors-teal-teal-300);
--color-util-colors-teal-teal-400: var(--color-util-colors-teal-teal-400);
--color-util-colors-teal-teal-500: var(--color-util-colors-teal-teal-500);
--color-util-colors-teal-teal-600: var(--color-util-colors-teal-teal-600);
--color-util-colors-teal-teal-700: var(--color-util-colors-teal-teal-700);
--color-util-colors-cyan-cyan-50: var(--color-util-colors-cyan-cyan-50);
--color-util-colors-cyan-cyan-100: var(--color-util-colors-cyan-cyan-100);
--color-util-colors-cyan-cyan-200: var(--color-util-colors-cyan-cyan-200);
--color-util-colors-cyan-cyan-300: var(--color-util-colors-cyan-cyan-300);
--color-util-colors-cyan-cyan-400: var(--color-util-colors-cyan-cyan-400);
--color-util-colors-cyan-cyan-500: var(--color-util-colors-cyan-cyan-500);
--color-util-colors-cyan-cyan-600: var(--color-util-colors-cyan-cyan-600);
--color-util-colors-cyan-cyan-700: var(--color-util-colors-cyan-cyan-700);
--color-util-colors-violet-violet-50: var(--color-util-colors-violet-violet-50);
--color-util-colors-violet-violet-100: var(--color-util-colors-violet-violet-100);
--color-util-colors-violet-violet-200: var(--color-util-colors-violet-violet-200);
--color-util-colors-violet-violet-300: var(--color-util-colors-violet-violet-300);
--color-util-colors-violet-violet-400: var(--color-util-colors-violet-violet-400);
--color-util-colors-violet-violet-500: var(--color-util-colors-violet-violet-500);
--color-util-colors-violet-violet-600: var(--color-util-colors-violet-violet-600);
--color-util-colors-violet-violet-700: var(--color-util-colors-violet-violet-700);
--color-util-colors-gray-gray-50: var(--color-util-colors-gray-gray-50);
--color-util-colors-gray-gray-100: var(--color-util-colors-gray-gray-100);
--color-util-colors-gray-gray-200: var(--color-util-colors-gray-gray-200);
--color-util-colors-gray-gray-300: var(--color-util-colors-gray-gray-300);
--color-util-colors-gray-gray-400: var(--color-util-colors-gray-gray-400);
--color-util-colors-gray-gray-500: var(--color-util-colors-gray-gray-500);
--color-util-colors-gray-gray-600: var(--color-util-colors-gray-gray-600);
--color-util-colors-gray-gray-700: var(--color-util-colors-gray-gray-700);
--color-util-colors-green-light-green-light-50: var(--color-util-colors-green-light-green-light-50);
--color-util-colors-green-light-green-light-100: var(--color-util-colors-green-light-green-light-100);
--color-util-colors-green-light-green-light-200: var(--color-util-colors-green-light-green-light-200);
--color-util-colors-green-light-green-light-300: var(--color-util-colors-green-light-green-light-300);
--color-util-colors-green-light-green-light-500: var(--color-util-colors-green-light-green-light-500);
--color-util-colors-green-light-green-light-400: var(--color-util-colors-green-light-green-light-400);
--color-util-colors-green-light-green-light-600: var(--color-util-colors-green-light-green-light-600);
--color-util-colors-green-light-green-light-700: var(--color-util-colors-green-light-green-light-700);
--color-util-colors-rose-rose-50: var(--color-util-colors-rose-rose-50);
--color-util-colors-rose-rose-100: var(--color-util-colors-rose-rose-100);
--color-util-colors-rose-rose-200: var(--color-util-colors-rose-rose-200);
--color-util-colors-rose-rose-300: var(--color-util-colors-rose-rose-300);
--color-util-colors-rose-rose-400: var(--color-util-colors-rose-rose-400);
--color-util-colors-rose-rose-500: var(--color-util-colors-rose-rose-500);
--color-util-colors-rose-rose-600: var(--color-util-colors-rose-rose-600);
--color-util-colors-rose-rose-700: var(--color-util-colors-rose-rose-700);
--color-util-colors-midnight-midnight-50: var(--color-util-colors-midnight-midnight-50);
--color-util-colors-midnight-midnight-100: var(--color-util-colors-midnight-midnight-100);
--color-util-colors-midnight-midnight-200: var(--color-util-colors-midnight-midnight-200);
--color-util-colors-midnight-midnight-300: var(--color-util-colors-midnight-midnight-300);
--color-util-colors-midnight-midnight-400: var(--color-util-colors-midnight-midnight-400);
--color-util-colors-midnight-midnight-500: var(--color-util-colors-midnight-midnight-500);
--color-util-colors-midnight-midnight-600: var(--color-util-colors-midnight-midnight-600);
--color-util-colors-midnight-midnight-700: var(--color-util-colors-midnight-midnight-700);
--color-third-party-LangChain: var(--color-third-party-LangChain);
--color-third-party-Langfuse: var(--color-third-party-Langfuse);
--color-third-party-Github: var(--color-third-party-Github);
--color-third-party-Github-tertiary: var(--color-third-party-Github-tertiary);
--color-third-party-Github-secondary: var(--color-third-party-Github-secondary);
--color-third-party-model-bg-openai: var(--color-third-party-model-bg-openai);
--color-third-party-model-bg-anthropic: var(--color-third-party-model-bg-anthropic);
--color-third-party-model-bg-default: var(--color-third-party-model-bg-default);
--color-third-party-aws: var(--color-third-party-aws);
--color-third-party-aws-alt: var(--color-third-party-aws-alt);
--color-saas-background: var(--color-saas-background);
--color-saas-pricing-grid-bg: var(--color-saas-pricing-grid-bg);
--color-saas-dify-blue-static: var(--color-saas-dify-blue-static);
--color-saas-dify-blue-static-hover: var(--color-saas-dify-blue-static-hover);
--color-saas-dify-blue-accessible: var(--color-saas-dify-blue-accessible);
--color-saas-dify-blue-inverted: var(--color-saas-dify-blue-inverted);
--color-saas-dify-blue-inverted-dimmed: var(--color-saas-dify-blue-inverted-dimmed);
--color-saas-background-inverted: var(--color-saas-background-inverted);
--color-saas-background-inverted-hover: var(--color-saas-background-inverted-hover);
--color-dify-logo-blue: var(--color-dify-logo-blue);
--color-dify-logo-black: var(--color-dify-logo-black);
}

View File

@ -1,23 +0,0 @@
import type { Config } from 'tailwindcss'
import { getIconCollections, iconsPlugin } from '@egoist/tailwindcss-icons'
import difyUIPreset from './src/tailwind-preset'
const config: Config = {
content: [
'./src/**/*.{js,ts,jsx,tsx,mdx}',
'./.storybook/**/*.{js,ts,jsx,tsx,mdx}',
],
presets: [difyUIPreset],
plugins: [
iconsPlugin({
collections: getIconCollections(['ri']),
extraProperties: {
width: '1rem',
height: '1rem',
display: 'block',
},
}),
],
}
export default config

View File

@ -3,6 +3,6 @@
"compilerOptions": {
"types": ["vite-plus/test/globals"]
},
"include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.ts", "tailwind.config.ts"],
"include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.ts"],
"exclude": ["node_modules", "dist", "storybook-static", "coverage"]
}

View File

@ -6,7 +6,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { I18nClientProvider as I18N } from '../app/components/provider/i18n'
import commonEnUS from '../i18n/en-US/common.json'
import '../app/styles/globals.css'
import '../app/styles/markdown.css'
import './storybook.css'

View File

@ -1,3 +1,16 @@
@import '../app/styles/tailwind-core.css';
@source '../app';
@source '../context';
@source '../hooks';
@source '.';
@source '../../packages/dify-ui/src';
@source '../node_modules/streamdown/dist';
@source '../node_modules/@streamdown/math/dist';
@source not '../**/*.{spec,test}.{js,ts,jsx,tsx}';
@source not '../../packages/dify-ui/src/**/*.{spec,test}.{ts,tsx}';
@source not '../../packages/dify-ui/src/**/*.stories.{ts,tsx}';
html,
body {
max-width: unset;

View File

@ -255,7 +255,6 @@ const TestThemeProvider = ({ children }: { children: React.ReactNode }) => (
defaultTheme="system"
enableSystem
disableTransitionOnChange
enableColorScheme={false}
>
{children}
</ThemeProvider>

View File

@ -15,9 +15,9 @@ import type {
import { cn } from '@langgenius/dify-ui/cn'
import { Select, SelectContent, SelectItem, SelectItemIndicator, SelectItemText, SelectTrigger } from '@langgenius/dify-ui/select'
import { useCallback, useState } from 'react'
import { Infotip } from '@/app/components/base/infotip'
import Radio from '@/app/components/base/radio'
import RadioE from '@/app/components/base/radio/ui'
import Tooltip from '@/app/components/base/tooltip'
import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector'
import ModelParameterModal from '@/app/components/plugins/plugin-detail-panel/model-selector'
import MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector'
@ -28,6 +28,23 @@ import { FormTypeEnum } from '../declarations'
import { useLanguage } from '../hooks'
import Input from './Input'
const radioGridColumnsClassNames: Record<number, string> = {
1: 'grid-cols-1',
2: 'grid-cols-2',
3: 'grid-cols-3',
4: 'grid-cols-4',
5: 'grid-cols-5',
6: 'grid-cols-6',
7: 'grid-cols-7',
8: 'grid-cols-8',
9: 'grid-cols-9',
10: 'grid-cols-10',
11: 'grid-cols-11',
12: 'grid-cols-12',
}
type ModelSelectorValue = Record<string, unknown>
type FormProps<
CustomFormSchema extends Omit<CredentialFormSchema, 'type'> & { type: string } = never,
> = {
@ -100,7 +117,7 @@ function Form<
fieldMoreInfo,
}
const handleFormChange = (key: string, val: string | boolean) => {
const handleFormChange = (key: string, val: FormValue[string]) => {
if (isEditMode && (key === '__model_type' || key === '__model_name'))
return
@ -115,7 +132,7 @@ function Form<
onChange({ ...value, [key]: val, ...shouldClearVariable })
}
const handleModelChanged = useCallback((key: string, model: any) => {
const handleModelChanged = useCallback((key: string, model: ModelSelectorValue) => {
const newValue = {
...value[key],
...model,
@ -125,17 +142,16 @@ function Form<
}, [onChange, value])
const renderField = (formSchema: CredentialFormSchema | CustomFormSchema) => {
const tooltip = formSchema.tooltip
const tooltipContent = (tooltip && (
<Tooltip
popupContent={(
<div className="w-[200px]">
{tooltip[language] || tooltip.en_US}
</div>
)}
triggerClassName="ml-1 w-4 h-4"
asChild={false}
/>
const infotip = formSchema.tooltip
const infotipText = infotip?.[language] || infotip?.en_US
const infotipContent = (infotipText && (
<Infotip
aria-label={infotipText}
className="ml-1"
popupClassName="w-[200px] max-w-[200px]"
>
{infotipText}
</Infotip>
))
if (override) {
const [overrideTypes, overrideRender] = override
@ -166,7 +182,7 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<Input
className={cn(inputClassName, `${disabled && 'cursor-not-allowed opacity-60'}`)}
@ -201,6 +217,7 @@ function Form<
return null
const disabled = isEditMode && (variable === '__model_type' || variable === '__model_name')
const gridColumnsClassName = radioGridColumnsClassNames[options.length] ?? 'grid-cols-1'
return (
<div key={variable} className={cn(itemClassName, 'py-3')}>
@ -209,10 +226,9 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
{/* eslint-disable-next-line tailwindcss/no-unknown-classes */}
<div className={cn('grid gap-3', `grid-cols-${options?.length}`)}>
<div className={cn('grid gap-3', gridColumnsClassName)}>
{options.filter((option) => {
if (option.show_on.length)
return option.show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)
@ -272,7 +288,7 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<Select
disabled={readonly}
@ -320,7 +336,7 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<Radio.Group
className="flex items-center"
@ -350,7 +366,7 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<ModelParameterModal
popupClassName="w-[387px]!"
@ -382,7 +398,7 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<ToolSelector
scope={scope}
@ -392,8 +408,8 @@ function Form<
disabled={readonly}
value={value[variable]}
// selectedTools={value[variable] ? [value[variable]] : []}
onSelect={item => handleFormChange(variable, item as any)}
onDelete={() => handleFormChange(variable, null as any)}
onSelect={item => handleFormChange(variable, item)}
onDelete={() => handleFormChange(variable, null)}
/>
{fieldMoreInfo?.(formSchema)}
{validating && changeKey === variable && <ValidatingTip />}
@ -405,7 +421,7 @@ function Form<
const {
variable,
label,
tooltip,
tooltip: infotip,
required,
scope,
} = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput)
@ -420,9 +436,9 @@ function Form<
scope={scope}
label={label[language] || label.en_US}
required={required}
tooltip={tooltip?.[language] || tooltip?.en_US}
tooltip={infotip?.[language] || infotip?.en_US}
value={value[variable] || []}
onChange={item => handleFormChange(variable, item as any)}
onChange={item => handleFormChange(variable, item)}
supportCollapse
/>
{fieldMoreInfo?.(formSchema)}
@ -446,13 +462,13 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<AppSelector
disabled={readonly}
scope={scope}
value={value[variable]}
onSelect={item => handleFormChange(variable, { ...item, type: FormTypeEnum.appSelector } as any)}
onSelect={item => handleFormChange(variable, { ...item, type: FormTypeEnum.appSelector })}
/>
{fieldMoreInfo?.(formSchema)}
{validating && changeKey === variable && <ValidatingTip />}
@ -475,7 +491,7 @@ function Form<
{required && (
<span className="ml-1 text-red-500">*</span>
)}
{tooltipContent}
{infotipContent}
</div>
<VarReferencePicker
zIndex={1001}
@ -483,7 +499,7 @@ function Form<
isShowNodeName
nodeId={nodeId || ''}
value={value[variable] || []}
onChange={item => handleFormChange(variable, item as any)}
onChange={item => handleFormChange(variable, item)}
filterVar={(varPayload) => {
if (!scope)
return true

View File

@ -1235,6 +1235,10 @@ describe('Form', () => {
expect(screen.getByText('Region'))!.toBeInTheDocument()
expect(screen.getByText('Model'))!.toBeInTheDocument()
expect(screen.getByText('Agree'))!.toBeInTheDocument()
expect(screen.getByLabelText('Enter your API key here'))!.toBeInTheDocument()
expect(screen.getByLabelText('Select region'))!.toBeInTheDocument()
expect(screen.getByLabelText('Choose model'))!.toBeInTheDocument()
expect(screen.getByLabelText('Agree tooltip'))!.toBeInTheDocument()
})
it('should render required asterisk for radio, select, checkbox, and other field types', () => {

View File

@ -27,6 +27,12 @@ const reactFlowBridge = vi.hoisted(() => ({
const collaborationBridge = vi.hoisted(() => ({
graphImportHandler: null as null | ((payload: { nodes: Node[], edges: Edge[] }) => void),
historyActionHandler: null as null | ((payload: unknown) => void),
restoreIntentHandler: null as null | ((payload: {
versionId: string
versionName?: string
initiatorUserId: string
initiatorName: string
}) => void),
}))
const toastInfoMock = vi.hoisted(() => vi.fn())
@ -180,6 +186,10 @@ vi.mock('../collaboration/core/collaboration-manager', () => ({
collaborationBridge.historyActionHandler = handler
return vi.fn()
},
onRestoreIntent: (handler: typeof collaborationBridge.restoreIntentHandler) => {
collaborationBridge.restoreIntentHandler = handler
return vi.fn()
},
},
}))
@ -401,7 +411,6 @@ vi.mock('../hooks', () => ({
useWorkflowRefreshDraft: () => ({
handleRefreshWorkflowDraft: vi.fn(),
}),
useLeaderRestoreListener: vi.fn(),
}))
vi.mock('../hooks/use-workflow-search', () => ({
@ -479,6 +488,7 @@ describe('Workflow edge event wiring', () => {
reactFlowBridge.store = null
collaborationBridge.graphImportHandler = null
collaborationBridge.historyActionHandler = null
collaborationBridge.restoreIntentHandler = null
workflowCommentState.comments = []
workflowCommentState.pendingComment = null
workflowCommentState.activeComment = null
@ -626,6 +636,25 @@ describe('Workflow edge event wiring', () => {
})
})
it('should show restore intent toast when another collaborator restores a workflow version', async () => {
renderSubject()
act(() => {
collaborationBridge.restoreIntentHandler?.({
versionId: 'version-1',
versionName: 'Version One',
initiatorUserId: 'user-1',
initiatorName: 'Alice',
})
})
await waitFor(() => {
expect(toastInfoMock).toHaveBeenCalledWith(
'workflow.versionHistory.action.restoreInProgress:{"userName":"Alice","versionName":"Version One"}',
)
})
})
it('should render comment overlays and execute comment actions in comment mode', async () => {
workflowCommentState.comments = [
{ id: 'comment-1', resolved: false },

View File

@ -1,5 +1,5 @@
import type { LoroMap } from 'loro-crdt'
import type { OnlineUser, RestoreRequestData } from '../../types/collaboration'
import type { OnlineUser } from '../../types/collaboration'
import type { NoteNodeType } from '@/app/components/workflow/note-node/types'
import type { Edge, Node } from '@/app/components/workflow/types'
import { LoroDoc } from 'loro-crdt'
@ -67,18 +67,6 @@ const createEdge = (id: string, source: string, target: string): Edge => ({
},
})
const createRestoreRequestData = (): RestoreRequestData => ({
versionId: 'version-1',
versionName: 'Version One',
initiatorUserId: 'user-1',
initiatorName: 'Alice',
graphData: {
nodes: [createNode('n-restore')],
edges: [],
viewport: { x: 1, y: 2, zoom: 0.5 },
},
})
const setupManagerWithDoc = () => {
const manager = new CollaborationManager()
const doc = new LoroDoc()
@ -275,7 +263,6 @@ describe('CollaborationManager logs and event helpers', () => {
manager.emitCommentsUpdate('app-1')
manager.emitHistoryAction('undo')
manager.emitRestoreRequest(createRestoreRequestData())
manager.emitRestoreIntent({
versionId: 'version-1',
versionName: 'Version One',
@ -289,13 +276,11 @@ describe('CollaborationManager logs and event helpers', () => {
manager.emitCommentsUpdate('app-1')
manager.emitHistoryAction('undo')
manager.emitRestoreRequest(createRestoreRequestData())
expect(sendSpy).not.toHaveBeenCalled()
isConnectedSpy.mockReturnValue(true)
manager.emitCommentsUpdate('app-1')
manager.emitHistoryAction('redo')
manager.emitRestoreRequest(createRestoreRequestData())
manager.emitRestoreIntent({
versionId: 'version-2',
initiatorUserId: 'u-2',
@ -309,7 +294,6 @@ describe('CollaborationManager logs and event helpers', () => {
expect(eventTypes).toEqual([
'comments_update',
'workflow_history_action',
'workflow_restore_request',
'workflow_restore_intent',
'workflow_restore_complete',
])

View File

@ -203,7 +203,6 @@ describe('CollaborationManager socket and subscription behavior', () => {
const mcpHandler = vi.fn()
const workflowUpdateHandler = vi.fn()
const commentsHandler = vi.fn()
const restoreRequestHandler = vi.fn()
const restoreIntentHandler = vi.fn()
const restoreCompleteHandler = vi.fn()
const historyHandler = vi.fn()
@ -218,7 +217,6 @@ describe('CollaborationManager socket and subscription behavior', () => {
manager.onMcpServerUpdate(mcpHandler)
manager.onWorkflowUpdate(workflowUpdateHandler)
manager.onCommentsUpdate(commentsHandler)
manager.onRestoreRequest(restoreRequestHandler)
manager.onRestoreIntent(restoreIntentHandler)
manager.onRestoreComplete(restoreCompleteHandler)
manager.onHistoryAction(historyHandler)
@ -296,11 +294,6 @@ describe('CollaborationManager socket and subscription behavior', () => {
type: 'graph_resync_request',
data: {},
} satisfies CollaborationUpdate)
socket.trigger('collaboration_update', {
...baseUpdate,
type: 'workflow_restore_request',
data: { versionId: 'v1', initiatorUserId: 'u-1', initiatorName: 'Alice', graphData: { nodes: [], edges: [] } } as unknown as Record<string, unknown>,
} satisfies CollaborationUpdate)
socket.trigger('collaboration_update', {
...baseUpdate,
type: 'workflow_restore_intent',
@ -335,7 +328,6 @@ describe('CollaborationManager socket and subscription behavior', () => {
expect(latestPresence).toMatchObject({ 'n-1': { 'socket-events': { userId: 'u-1' } } })
expect(syncRequestHandler).toHaveBeenCalledTimes(1)
expect(broadcastSpy).toHaveBeenCalledTimes(1)
expect(restoreRequestHandler).toHaveBeenCalledTimes(1)
expect(restoreIntentHandler).toHaveBeenCalledWith({ versionId: 'v1', initiatorUserId: 'u-1', initiatorName: 'Alice' } satisfies RestoreIntentData)
expect(restoreCompleteHandler).toHaveBeenCalledWith({ versionId: 'v1', success: true } satisfies RestoreCompleteData)
expect(historyHandler).toHaveBeenCalledWith({ action: 'undo', userId: 'u-1' })

View File

@ -16,7 +16,6 @@ import type {
OnlineUser,
RestoreCompleteData,
RestoreIntentData,
RestoreRequestData,
} from '../types/collaboration'
import { cloneDeep } from 'es-toolkit/object'
import { isEqual } from 'es-toolkit/predicate'
@ -770,17 +769,6 @@ export class CollaborationManager {
return this.eventEmitter.on('historyAction', callback)
}
emitRestoreRequest(data: RestoreRequestData): void {
if (!this.currentAppId || !webSocketClient.isConnected(this.currentAppId))
return
this.sendCollaborationEvent({
type: 'workflow_restore_request',
data: data as unknown as Record<string, unknown>,
timestamp: Date.now(),
})
}
emitRestoreIntent(data: RestoreIntentData): void {
if (!this.currentAppId || !webSocketClient.isConnected(this.currentAppId))
return
@ -803,10 +791,6 @@ export class CollaborationManager {
})
}
onRestoreRequest(callback: (data: RestoreRequestData) => void): () => void {
return this.eventEmitter.on('restoreRequest', callback)
}
onRestoreIntent(callback: (data: RestoreIntentData) => void): () => void {
return this.eventEmitter.on('restoreIntent', callback)
}
@ -1476,10 +1460,6 @@ export class CollaborationManager {
if (this.isLeader)
this.broadcastCurrentGraph()
}
else if (update.type === 'workflow_restore_request') {
if (this.isLeader)
this.eventEmitter.emit('restoreRequest', update.data as RestoreRequestData)
}
else if (update.type === 'workflow_restore_intent') {
this.eventEmitter.emit('restoreIntent', update.data as RestoreIntentData)
}

View File

@ -1,7 +1,3 @@
import type { Viewport } from 'reactflow'
import type { ConversationVariable, Edge, EnvironmentVariable, Node } from '../../types'
import type { Features } from '@/app/components/base/features/types'
export type OnlineUser = {
user_id: string
username: string
@ -51,7 +47,6 @@ type CollaborationEventType
| 'node_panel_presence'
| 'app_publish_update'
| 'graph_resync_request'
| 'workflow_restore_request'
| 'workflow_restore_intent'
| 'workflow_restore_complete'
| 'workflow_history_action'
@ -63,21 +58,6 @@ export type CollaborationUpdate = {
timestamp: number
}
export type RestoreRequestData = {
versionId: string
versionName?: string
initiatorUserId: string
initiatorName: string
graphData: {
nodes: Node[]
edges: Edge[]
viewport?: Viewport
}
features?: Features
environmentVariables?: EnvironmentVariable[]
conversationVariables?: ConversationVariable[]
}
export type RestoreIntentData = {
versionId: string
versionName?: string

View File

@ -7,9 +7,9 @@ import HeaderInRestoring from '../header-in-restoring'
const mockRestoreWorkflow = vi.fn()
const mockInvalidAllLastRun = vi.fn()
const mockResetWorkflowVersionHistory = vi.fn()
const mockHandleLoadBackupDraft = vi.fn()
const mockHandleRefreshWorkflowDraft = vi.fn()
const mockRequestRestore = vi.fn()
vi.mock('@/hooks/use-theme', () => ({
default: () => ({
@ -31,6 +31,7 @@ vi.mock('@/hooks/use-format-time-from-now', () => ({
vi.mock('@/service/use-workflow', () => ({
useInvalidAllLastRun: () => mockInvalidAllLastRun,
useResetWorkflowVersionHistory: () => mockResetWorkflowVersionHistory,
useRestoreWorkflow: () => ({
mutateAsync: mockRestoreWorkflow,
}),
@ -43,9 +44,6 @@ vi.mock('../../hooks', () => ({
useWorkflowRefreshDraft: () => ({
handleRefreshWorkflowDraft: mockHandleRefreshWorkflowDraft,
}),
useLeaderRestore: () => ({
requestRestore: mockRequestRestore,
}),
}))
const createVersion = (overrides: Partial<VersionHistory> = {}): VersionHistory => ({
@ -92,7 +90,7 @@ describe('HeaderInRestoring', () => {
expect(screen.getByRole('button', { name: 'workflow.common.restore' })).toBeDisabled()
})
it('should enable restore when version and flow config are both ready', () => {
it('should enable restore when version and flow id are both ready', () => {
renderWorkflowComponent(<HeaderInRestoring />, {
initialStoreState: {
currentVersion: createVersion(),
@ -100,7 +98,7 @@ describe('HeaderInRestoring', () => {
hooksStoreProps: {
configsMap: {
flowId: 'app-1',
flowType: FlowType.appFlow,
flowType: undefined as never,
fileSettings: {} as never,
},
},

View File

@ -14,7 +14,11 @@ const mockHandleNodeSelect = vi.fn()
const mockHandleRefreshWorkflowDraft = vi.fn()
const mockCloseAllInputFieldPanels = vi.fn()
const mockInvalidAllLastRun = vi.fn()
const mockRequestRestore = vi.fn()
const mockRestoreWorkflow = vi.fn()
const mockResetWorkflowVersionHistory = vi.fn()
const mockEmitRestoreIntent = vi.fn()
const mockEmitRestoreComplete = vi.fn()
const mockEmitWorkflowUpdate = vi.fn()
const mockNotify = vi.fn()
const mockRunAndHistory = vi.fn()
const mockViewHistory = vi.fn()
@ -33,9 +37,6 @@ vi.mock('../../hooks', () => ({
handleBackupDraft: mockHandleBackupDraft,
handleLoadBackupDraft: mockHandleLoadBackupDraft,
}),
useLeaderRestore: () => ({
requestRestore: mockRequestRestore,
}),
useNodesSyncDraft: () => ({
handleSyncWorkflowDraft: vi.fn(),
}),
@ -58,6 +59,18 @@ vi.mock('@/hooks/use-theme', () => ({
vi.mock('@/service/use-workflow', () => ({
useInvalidAllLastRun: () => mockInvalidAllLastRun,
useResetWorkflowVersionHistory: () => mockResetWorkflowVersionHistory,
useRestoreWorkflow: () => ({
mutateAsync: mockRestoreWorkflow,
}),
}))
vi.mock('../../collaboration/core/collaboration-manager', () => ({
collaborationManager: {
emitRestoreIntent: mockEmitRestoreIntent,
emitRestoreComplete: mockEmitRestoreComplete,
emitWorkflowUpdate: mockEmitWorkflowUpdate,
},
}))
vi.mock('@langgenius/dify-ui/toast', () => ({
@ -166,13 +179,7 @@ describe('Header layout components', () => {
mockNodesReadOnly = false
mockTheme = 'light'
mockUseNodes.mockReturnValue([])
mockRequestRestore.mockImplementation((_payload: unknown, callbacks?: {
onSuccess?: () => void
onSettled?: () => void
}) => {
callbacks?.onSuccess?.()
callbacks?.onSettled?.()
})
mockRestoreWorkflow.mockResolvedValue({})
})
describe('HeaderInNormal', () => {
@ -277,7 +284,7 @@ describe('Header layout components', () => {
fireEvent.click(screen.getByRole('button', { name: 'workflow.common.restore' }))
await waitFor(() => {
expect(mockRequestRestore).toHaveBeenCalledTimes(1)
expect(mockRestoreWorkflow).toHaveBeenCalledWith('/apps/flow-1/workflows/version-1/restore')
expect(store.getState().showWorkflowVersionHistoryPanel).toBe(false)
expect(store.getState().isRestoring).toBe(false)
expect(store.getState().backupDraft).toBeUndefined()
@ -289,8 +296,53 @@ describe('Header layout components', () => {
message: 'workflow.versionHistory.action.restoreSuccess',
})
})
expect(mockEmitRestoreIntent).toHaveBeenCalledWith({
versionId: currentVersion.id,
versionName: currentVersion.marked_name,
initiatorUserId: '',
initiatorName: '',
})
expect(mockEmitRestoreComplete).toHaveBeenCalledWith({
versionId: currentVersion.id,
success: true,
})
expect(mockEmitWorkflowUpdate).toHaveBeenCalledWith('flow-1')
expect(mockResetWorkflowVersionHistory).toHaveBeenCalledTimes(1)
expect(onRestoreSettled).toHaveBeenCalledTimes(1)
})
it('should restore rag pipeline versions without emitting collaboration events', async () => {
const currentVersion = createCurrentVersion()
renderWorkflowComponent(
<HeaderInRestoring />,
{
initialStoreState: {
isRestoring: true,
showWorkflowVersionHistoryPanel: true,
backupDraft: createBackupDraft(),
currentVersion,
},
hooksStoreProps: {
configsMap: {
flowType: FlowType.ragPipeline,
flowId: 'pipeline-1',
fileSettings: {},
},
},
},
)
fireEvent.click(screen.getByRole('button', { name: 'workflow.common.restore' }))
await waitFor(() => {
expect(mockRestoreWorkflow).toHaveBeenCalledWith('/rag/pipelines/pipeline-1/workflows/version-1/restore')
expect(mockHandleRefreshWorkflowDraft).toHaveBeenCalledTimes(1)
})
expect(mockEmitRestoreIntent).not.toHaveBeenCalled()
expect(mockEmitRestoreComplete).not.toHaveBeenCalled()
expect(mockEmitWorkflowUpdate).not.toHaveBeenCalled()
})
})
describe('HeaderInHistory', () => {

View File

@ -6,12 +6,11 @@ import {
useCallback,
} from 'react'
import { useTranslation } from 'react-i18next'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { useSelector as useAppContextSelector } from '@/context/app-context'
import useTheme from '@/hooks/use-theme'
import { useInvalidAllLastRun } from '@/service/use-workflow'
import { useInvalidAllLastRun, useResetWorkflowVersionHistory, useRestoreWorkflow } from '@/service/use-workflow'
import { FlowType } from '@/types/common'
import {
useLeaderRestore,
useWorkflowRefreshDraft,
useWorkflowRun,
} from '../hooks'
@ -35,7 +34,6 @@ const HeaderInRestoring = ({
const { theme } = useTheme()
const workflowStore = useWorkflowStore()
const userProfile = useAppContextSelector(s => s.userProfile)
const featuresStore = useFeaturesStore()
const configsMap = useHooksStore(s => s.configsMap)
const invalidAllLastRun = useInvalidAllLastRun(configsMap?.flowType, configsMap?.flowId)
const {
@ -47,9 +45,11 @@ const HeaderInRestoring = ({
const {
handleLoadBackupDraft,
} = useWorkflowRun()
const { requestRestore } = useLeaderRestore()
const { handleRefreshWorkflowDraft } = useWorkflowRefreshDraft()
const { mutateAsync: restoreWorkflow } = useRestoreWorkflow()
const resetWorkflowVersionHistory = useResetWorkflowVersionHistory()
const canRestore = !!currentVersion?.id && !!configsMap?.flowId && currentVersion.version !== WorkflowVersion.Draft
const canEmitCollaborationEvents = configsMap?.flowType === FlowType.appFlow
const handleCancelRestore = useCallback(() => {
handleLoadBackupDraft()
@ -57,47 +57,86 @@ const HeaderInRestoring = ({
setShowWorkflowVersionHistoryPanel(false)
}, [workflowStore, handleLoadBackupDraft, setShowWorkflowVersionHistoryPanel])
const handleRestore = useCallback(() => {
const restoreVersionUrl = useCallback((versionId: string) => {
if (!configsMap?.flowId)
return ''
if (configsMap.flowType === FlowType.ragPipeline)
return `/rag/pipelines/${configsMap.flowId}/workflows/${versionId}/restore`
return `/apps/${configsMap.flowId}/workflows/${versionId}/restore`
}, [configsMap?.flowId, configsMap?.flowType])
const emitRestoreIntent = useCallback(async () => {
if (!currentVersion || !canEmitCollaborationEvents)
return
try {
const { collaborationManager } = await import('../collaboration/core/collaboration-manager')
collaborationManager.emitRestoreIntent({
versionId: currentVersion.id,
versionName: currentVersion.marked_name,
initiatorUserId: userProfile.id,
initiatorName: userProfile.name,
})
}
catch (error) {
console.error('Failed to emit restore intent:', error)
}
}, [canEmitCollaborationEvents, currentVersion, userProfile.id, userProfile.name])
const emitRestoreComplete = useCallback(async (success: boolean, errorMessage?: string) => {
if (!currentVersion || !canEmitCollaborationEvents)
return
try {
const { collaborationManager } = await import('../collaboration/core/collaboration-manager')
collaborationManager.emitRestoreComplete({
versionId: currentVersion.id,
success,
...(errorMessage ? { error: errorMessage } : {}),
})
}
catch (error) {
console.error('Failed to emit restore complete:', error)
}
}, [canEmitCollaborationEvents, currentVersion])
const emitWorkflowUpdate = useCallback(async () => {
if (!configsMap?.flowId || !canEmitCollaborationEvents)
return
try {
const { collaborationManager } = await import('../collaboration/core/collaboration-manager')
collaborationManager.emitWorkflowUpdate(configsMap.flowId)
}
catch (error) {
console.error('Failed to emit workflow update:', error)
}
}, [canEmitCollaborationEvents, configsMap?.flowId])
const handleRestore = useCallback(async () => {
if (!canRestore || !currentVersion)
return
setShowWorkflowVersionHistoryPanel(false)
workflowStore.setState({ isRestoring: false })
workflowStore.setState({ backupDraft: undefined })
await emitRestoreIntent()
const { graph } = currentVersion
const features = featuresStore?.getState().features
const environmentVariables = currentVersion.environment_variables || []
const conversationVariables = currentVersion.conversation_variables || []
requestRestore({
versionId: currentVersion.id,
versionName: currentVersion.marked_name,
initiatorUserId: userProfile.id,
initiatorName: userProfile.name,
graphData: {
nodes: graph.nodes,
edges: graph.edges,
viewport: graph.viewport,
},
features,
environmentVariables,
conversationVariables,
}, {
onSuccess: () => {
handleRefreshWorkflowDraft()
toast.success(t('versionHistory.action.restoreSuccess', { ns: 'workflow' }))
deleteAllInspectVars()
invalidAllLastRun()
},
onError: () => {
toast.error(t('versionHistory.action.restoreFailure', { ns: 'workflow' }))
},
onSettled: () => {
onRestoreSettled?.()
},
})
}, [canRestore, currentVersion, setShowWorkflowVersionHistoryPanel, workflowStore, featuresStore, requestRestore, userProfile, handleRefreshWorkflowDraft, deleteAllInspectVars, invalidAllLastRun, t, onRestoreSettled])
try {
await restoreWorkflow(restoreVersionUrl(currentVersion.id))
workflowStore.setState({ isRestoring: false })
workflowStore.setState({ backupDraft: undefined })
handleRefreshWorkflowDraft()
toast.success(t('versionHistory.action.restoreSuccess', { ns: 'workflow' }))
deleteAllInspectVars()
invalidAllLastRun()
await emitRestoreComplete(true)
await emitWorkflowUpdate()
}
catch {
toast.error(t('versionHistory.action.restoreFailure', { ns: 'workflow' }))
await emitRestoreComplete(false, 'restore failed')
}
finally {
resetWorkflowVersionHistory()
onRestoreSettled?.()
}
}, [canRestore, currentVersion, setShowWorkflowVersionHistoryPanel, emitRestoreIntent, restoreWorkflow, restoreVersionUrl, workflowStore, handleRefreshWorkflowDraft, t, deleteAllInspectVars, invalidAllLastRun, emitRestoreComplete, emitWorkflowUpdate, resetWorkflowVersionHistory, onRestoreSettled])
return (
<>

View File

@ -1,262 +0,0 @@
import type { RestoreIntentData, RestoreRequestData } from '../../collaboration/types/collaboration'
import type { SyncDraftCallback } from '../../hooks-store/store'
import type { Edge, Node } from '../../types'
import { act, renderHook } from '@testing-library/react'
import { renderHookWithSystemFeatures } from '@/__tests__/utils/mock-system-features'
import { ChatVarType } from '../../panel/chat-variable-panel/type'
import { useLeaderRestore, useLeaderRestoreListener } from '../use-leader-restore'
const mockSetViewport = vi.hoisted(() => vi.fn())
const mockSetFeatures = vi.hoisted(() => vi.fn())
const mockSetEnvironmentVariables = vi.hoisted(() => vi.fn())
const mockSetConversationVariables = vi.hoisted(() => vi.fn())
const mockDoSyncWorkflowDraft = vi.hoisted(() => vi.fn())
const mockToastInfo = vi.hoisted(() => vi.fn())
const mockEmitRestoreIntent = vi.hoisted(() => vi.fn())
const mockEmitRestoreComplete = vi.hoisted(() => vi.fn())
const mockEmitWorkflowUpdate = vi.hoisted(() => vi.fn())
const mockEmitRestoreRequest = vi.hoisted(() => vi.fn())
const mockIsConnected = vi.hoisted(() => vi.fn())
const mockGetIsLeader = vi.hoisted(() => vi.fn())
const mockSetNodes = vi.hoisted(() => vi.fn())
const mockSetEdges = vi.hoisted(() => vi.fn())
const mockRefreshGraphSynchronously = vi.hoisted(() => vi.fn())
const mockGetNodes = vi.hoisted(() => vi.fn(() => [{ id: 'old-node' } as unknown as Node]))
const mockGetEdges = vi.hoisted(() => vi.fn(() => [{ id: 'old-edge' } as unknown as Edge]))
let restoreCompleteCallback: ((data: { versionId: string, success: boolean }) => void) | null = null
let restoreRequestCallback: ((data: RestoreRequestData) => void) | null = null
let restoreIntentCallback: ((data: RestoreIntentData) => void) | null = null
const unsubscribeRestoreComplete = vi.hoisted(() => vi.fn())
const unsubscribeRestoreRequest = vi.hoisted(() => vi.fn())
const unsubscribeRestoreIntent = vi.hoisted(() => vi.fn())
let isCollaborationEnabled = true
vi.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key: string, options?: { ns?: string, userName?: string, versionName?: string }) => {
const ns = options?.ns ? `${options.ns}.` : ''
const extra = options?.userName ? `:${options.userName}:${options.versionName}` : ''
return `${ns}${key}${extra}`
},
}),
}))
vi.mock('reactflow', () => ({
useReactFlow: () => ({
setViewport: mockSetViewport,
}),
}))
vi.mock('@/app/components/app/store', () => ({
useStore: {
getState: () => ({
appDetail: { id: 'app-1' },
}),
},
}))
vi.mock('@/app/components/base/features/hooks', () => ({
useFeaturesStore: () => ({
getState: () => ({
setFeatures: mockSetFeatures,
}),
}),
}))
vi.mock('@langgenius/dify-ui/toast', () => ({
toast: {
info: (...args: unknown[]) => mockToastInfo(...args),
},
}))
vi.mock('../../store', () => ({
useWorkflowStore: () => ({
getState: () => ({
setEnvironmentVariables: mockSetEnvironmentVariables,
setConversationVariables: mockSetConversationVariables,
}),
}),
}))
vi.mock('../use-nodes-sync-draft', () => ({
useNodesSyncDraft: () => ({
doSyncWorkflowDraft: (...args: unknown[]) => mockDoSyncWorkflowDraft(...args),
}),
}))
vi.mock('../../collaboration/core/collaboration-manager', () => ({
collaborationManager: {
emitRestoreIntent: (...args: unknown[]) => mockEmitRestoreIntent(...args),
emitRestoreComplete: (...args: unknown[]) => mockEmitRestoreComplete(...args),
emitWorkflowUpdate: (...args: unknown[]) => mockEmitWorkflowUpdate(...args),
emitRestoreRequest: (...args: unknown[]) => mockEmitRestoreRequest(...args),
isConnected: (...args: unknown[]) => mockIsConnected(...args),
getIsLeader: (...args: unknown[]) => mockGetIsLeader(...args),
setNodes: (...args: unknown[]) => mockSetNodes(...args),
setEdges: (...args: unknown[]) => mockSetEdges(...args),
refreshGraphSynchronously: (...args: unknown[]) => mockRefreshGraphSynchronously(...args),
getNodes: () => mockGetNodes(),
getEdges: () => mockGetEdges(),
onRestoreComplete: (callback: (data: { versionId: string, success: boolean }) => void) => {
restoreCompleteCallback = callback
return unsubscribeRestoreComplete
},
onRestoreRequest: (callback: (data: RestoreRequestData) => void) => {
restoreRequestCallback = callback
return unsubscribeRestoreRequest
},
onRestoreIntent: (callback: (data: RestoreIntentData) => void) => {
restoreIntentCallback = callback
return unsubscribeRestoreIntent
},
},
}))
describe('useLeaderRestore', () => {
const restoreData: RestoreRequestData = {
versionId: 'v-1',
versionName: 'Version One',
initiatorUserId: 'u-1',
initiatorName: 'Alice',
features: { moreLikeThis: { enabled: true } },
environmentVariables: [{ id: 'env-1', name: 'A', value: '1', value_type: ChatVarType.String, description: '' }],
conversationVariables: [{ id: 'conv-1', name: 'B', value: '2', value_type: ChatVarType.String, description: '' }],
graphData: {
nodes: [{ id: 'new-node' } as unknown as Node],
edges: [{ id: 'new-edge' } as unknown as Edge],
viewport: { x: 1, y: 2, zoom: 0.5 },
},
}
beforeEach(() => {
vi.clearAllMocks()
restoreCompleteCallback = null
restoreRequestCallback = null
restoreIntentCallback = null
isCollaborationEnabled = true
mockIsConnected.mockReturnValue(true)
mockGetIsLeader.mockReturnValue(false)
mockDoSyncWorkflowDraft.mockImplementation((_sync: boolean, callbacks?: SyncDraftCallback) => {
callbacks?.onSuccess?.()
callbacks?.onSettled?.()
})
})
it('performs restore locally when collaboration is disabled', async () => {
isCollaborationEnabled = false
const onSuccess = vi.fn()
const onSettled = vi.fn()
const { result } = renderHookWithSystemFeatures(() => useLeaderRestore(), {
systemFeatures: { enable_collaboration_mode: isCollaborationEnabled },
})
await act(async () => {
result.current.requestRestore(restoreData, { onSuccess, onSettled })
})
expect(mockEmitRestoreIntent).toHaveBeenCalledWith(expect.objectContaining({
versionId: 'v-1',
initiatorName: 'Alice',
}))
expect(mockSetFeatures).toHaveBeenCalledWith({ moreLikeThis: { enabled: true } })
expect(mockSetEnvironmentVariables).toHaveBeenCalled()
expect(mockSetConversationVariables).toHaveBeenCalled()
expect(mockSetNodes).toHaveBeenCalledWith([{ id: 'old-node' }], [{ id: 'new-node' }], 'leader-restore:apply-graph')
expect(mockSetEdges).toHaveBeenCalledWith([{ id: 'old-edge' }], [{ id: 'new-edge' }])
expect(mockRefreshGraphSynchronously).toHaveBeenCalled()
expect(mockSetViewport).toHaveBeenCalledWith({ x: 1, y: 2, zoom: 0.5 })
expect(mockEmitRestoreComplete).toHaveBeenCalledWith({ versionId: 'v-1', success: true })
expect(mockEmitWorkflowUpdate).toHaveBeenCalledWith('app-1')
expect(onSuccess).toHaveBeenCalled()
expect(onSettled).toHaveBeenCalled()
})
it('emits restore request and resolves callbacks from restore-complete events', async () => {
isCollaborationEnabled = true
mockIsConnected.mockReturnValue(true)
mockGetIsLeader.mockReturnValue(false)
const onSuccess = vi.fn()
const onError = vi.fn()
const onSettled = vi.fn()
const { result } = renderHookWithSystemFeatures(() => useLeaderRestore(), {
systemFeatures: { enable_collaboration_mode: isCollaborationEnabled },
})
act(() => {
result.current.requestRestore(restoreData, { onSuccess, onError, onSettled })
})
expect(mockEmitRestoreRequest).toHaveBeenCalledWith(restoreData)
expect(mockDoSyncWorkflowDraft).not.toHaveBeenCalled()
act(() => {
restoreCompleteCallback?.({ versionId: 'v-1', success: true })
})
expect(onSuccess).toHaveBeenCalledTimes(1)
expect(onSettled).toHaveBeenCalledTimes(1)
act(() => {
result.current.requestRestore(restoreData, { onSuccess, onError, onSettled })
restoreCompleteCallback?.({ versionId: 'v-1', success: false })
})
expect(onError).toHaveBeenCalledTimes(1)
expect(onSettled).toHaveBeenCalledTimes(2)
})
})
describe('useLeaderRestoreListener', () => {
beforeEach(() => {
vi.clearAllMocks()
restoreRequestCallback = null
restoreIntentCallback = null
mockDoSyncWorkflowDraft.mockImplementation((_sync: boolean, callbacks?: SyncDraftCallback) => {
callbacks?.onSuccess?.()
callbacks?.onSettled?.()
})
})
it('shows restore notifications for request and intent events', () => {
const { unmount } = renderHook(() => useLeaderRestoreListener())
act(() => {
restoreRequestCallback?.({
...{
versionId: 'v-2',
versionName: 'Version Two',
initiatorUserId: 'u-2',
initiatorName: 'Bob',
graphData: { nodes: [], edges: [] },
},
})
})
expect(mockToastInfo).toHaveBeenCalledWith(
'workflow.versionHistory.action.restoreInProgress:Bob:Version Two',
{ timeout: 3000 },
)
expect(mockEmitRestoreIntent).toHaveBeenCalled()
act(() => {
restoreIntentCallback?.({
versionId: 'v-3',
versionName: 'Version Three',
initiatorUserId: 'u-3',
initiatorName: 'Carol',
})
})
expect(mockToastInfo).toHaveBeenCalledWith(
'workflow.versionHistory.action.restoreInProgress:Carol:Version Three',
{ timeout: 3000 },
)
unmount()
expect(unsubscribeRestoreRequest).toHaveBeenCalled()
expect(unsubscribeRestoreIntent).toHaveBeenCalled()
})
})

View File

@ -4,7 +4,6 @@ export * from './use-checklist'
export * from './use-DSL'
export * from './use-edges-interactions'
export * from './use-inspect-vars-crud'
export * from './use-leader-restore'
export * from './use-node-data-update'
export * from './use-nodes-interactions'
export * from './use-nodes-meta-data'

View File

@ -1,164 +0,0 @@
import type { RestoreCompleteData, RestoreIntentData, RestoreRequestData } from '../collaboration/types/collaboration'
import type { SyncCallback } from './use-nodes-sync-draft'
import { toast } from '@langgenius/dify-ui/toast'
import { useSuspenseQuery } from '@tanstack/react-query'
import { useCallback, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useReactFlow } from 'reactflow'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { systemFeaturesQueryOptions } from '@/service/system-features'
import { collaborationManager } from '../collaboration/core/collaboration-manager'
import { useWorkflowStore } from '../store'
import { useNodesSyncDraft } from './use-nodes-sync-draft'
type RestoreCallbacks = SyncCallback
const usePerformRestore = () => {
const { doSyncWorkflowDraft } = useNodesSyncDraft()
const appDetail = useAppStore.getState().appDetail
const featuresStore = useFeaturesStore()
const workflowStore = useWorkflowStore()
const reactflow = useReactFlow()
return useCallback((data: RestoreRequestData, callbacks?: RestoreCallbacks) => {
collaborationManager.emitRestoreIntent({
versionId: data.versionId,
versionName: data.versionName,
initiatorUserId: data.initiatorUserId,
initiatorName: data.initiatorName,
})
if (data.features && featuresStore) {
const { setFeatures } = featuresStore.getState()
setFeatures(data.features)
}
if (data.environmentVariables) {
workflowStore.getState().setEnvironmentVariables(data.environmentVariables)
}
if (data.conversationVariables) {
workflowStore.getState().setConversationVariables(data.conversationVariables)
}
const { nodes, edges, viewport } = data.graphData
const currentNodes = collaborationManager.getNodes()
const currentEdges = collaborationManager.getEdges()
collaborationManager.setNodes(currentNodes, nodes, 'leader-restore:apply-graph')
collaborationManager.setEdges(currentEdges, edges)
collaborationManager.refreshGraphSynchronously()
if (viewport)
reactflow.setViewport(viewport)
doSyncWorkflowDraft(false, {
onSuccess: () => {
collaborationManager.emitRestoreComplete({
versionId: data.versionId,
success: true,
})
if (appDetail)
collaborationManager.emitWorkflowUpdate(appDetail.id)
callbacks?.onSuccess?.()
},
onError: () => {
collaborationManager.emitRestoreComplete({
versionId: data.versionId,
success: false,
error: 'Failed to sync restore to server',
})
callbacks?.onError?.()
},
onSettled: () => {
callbacks?.onSettled?.()
},
})
}, [appDetail, doSyncWorkflowDraft, featuresStore, reactflow, workflowStore])
}
export const useLeaderRestoreListener = () => {
const { t } = useTranslation()
const performRestore = usePerformRestore()
useEffect(() => {
const unsubscribe = collaborationManager.onRestoreRequest((data: RestoreRequestData) => {
toast.info(t('versionHistory.action.restoreInProgress', {
ns: 'workflow',
userName: data.initiatorName,
versionName: data.versionName || data.versionId,
}), { timeout: 3000 })
performRestore(data)
})
return unsubscribe
}, [performRestore, t])
useEffect(() => {
const unsubscribe = collaborationManager.onRestoreIntent((data: RestoreIntentData) => {
toast.info(t('versionHistory.action.restoreInProgress', {
ns: 'workflow',
userName: data.initiatorName,
versionName: data.versionName || data.versionId,
}), { timeout: 3000 })
})
return unsubscribe
}, [t])
}
export const useLeaderRestore = () => {
const performRestore = usePerformRestore()
const pendingCallbacksRef = useRef<{
versionId: string
callbacks: RestoreCallbacks | null
} | null>(null)
const { data: isCollaborationEnabled } = useSuspenseQuery({
...systemFeaturesQueryOptions(),
select: s => s.enable_collaboration_mode,
})
const requestRestore = useCallback((data: RestoreRequestData, callbacks?: RestoreCallbacks) => {
if (!isCollaborationEnabled || !collaborationManager.isConnected() || collaborationManager.getIsLeader()) {
performRestore(data, callbacks)
return
}
pendingCallbacksRef.current = {
versionId: data.versionId,
callbacks: callbacks || null,
}
collaborationManager.emitRestoreRequest(data)
}, [isCollaborationEnabled, performRestore])
useEffect(() => {
const unsubscribe = collaborationManager.onRestoreComplete((data: RestoreCompleteData) => {
const pending = pendingCallbacksRef.current
if (!pending || pending.versionId !== data.versionId)
return
const callbacks = pending.callbacks
if (!callbacks) {
pendingCallbacksRef.current = null
return
}
if (data.success)
callbacks.onSuccess?.()
else
callbacks.onError?.()
callbacks.onSettled?.()
pendingCallbacksRef.current = null
})
return unsubscribe
}, [])
return {
requestRestore,
}
}

View File

@ -81,7 +81,6 @@ import EdgeContextmenu from './edge-contextmenu'
import HelpLine from './help-line'
import {
useEdgesInteractions,
useLeaderRestoreListener,
useNodesInteractions,
useNodesReadOnly,
useNodesSyncDraft,
@ -277,6 +276,17 @@ export const Workflow: FC<WorkflowProps> = memo(({
toast.info(t('collaboration.historyAction.generic', { ns: 'workflow' }))
})
}, [t])
useEffect(() => {
return collaborationManager.onRestoreIntent((data) => {
toast.info(t('versionHistory.action.restoreInProgress', {
ns: 'workflow',
userName: data.initiatorName,
versionName: data.versionName || data.versionId,
}))
})
}, [t])
const {
handleSyncWorkflowDraft,
syncWorkflowDraftWhenPageClose,
@ -533,8 +543,6 @@ export const Workflow: FC<WorkflowProps> = memo(({
// Initialize workflow node search functionality
useWorkflowSearch()
useLeaderRestoreListener()
// Set up scroll to node event listener using the utility function
useEffect(() => {
return setupScrollToNodeListener(nodes, reactflow)

View File

@ -226,6 +226,11 @@ describe('node actions menu details', () => {
const user = userEvent.setup()
renderDropdownContent()
const deleteMenuItem = screen.getByText('common.operation.delete').closest('[role="menuitem"]')
expect(deleteMenuItem).toHaveAttribute('data-variant', 'default')
expect(deleteMenuItem).toHaveClass('text-text-secondary')
expect(deleteMenuItem).toHaveClass('data-highlighted:text-text-destructive')
await user.click(screen.getByText('workflow.panel.runThisStep'))
await user.click(screen.getByText('workflow.common.copy'))
await user.click(screen.getByText('workflow.common.duplicate'))

View File

@ -8,6 +8,7 @@ import {
import { useTranslation } from 'react-i18next'
import { ChangeBlockMenuTrigger } from './change-block-menu-trigger'
import {
NODE_ACTIONS_MENU_DELETE_ITEM_CLASS_NAME,
NODE_ACTIONS_MENU_ITEM_WITH_SHORTCUT_CLASS_NAME,
NodeActionsMenuAbout,
NodeActionsMenuItemContent,
@ -64,8 +65,7 @@ export function NodeActionsContextMenuContent(props: NodeActionsMenuProps) {
{hasDeleteGroup && (
<ContextMenuGroup>
<ContextMenuItem
variant="destructive"
className={NODE_ACTIONS_MENU_ITEM_WITH_SHORTCUT_CLASS_NAME}
className={NODE_ACTIONS_MENU_DELETE_ITEM_CLASS_NAME}
onClick={model.handleDelete}
>
<NodeActionsMenuItemContent shortcut="workflow.delete">

View File

@ -8,6 +8,7 @@ import {
import { useTranslation } from 'react-i18next'
import { ChangeBlockMenuTrigger } from './change-block-menu-trigger'
import {
NODE_ACTIONS_MENU_DELETE_ITEM_CLASS_NAME,
NODE_ACTIONS_MENU_ITEM_WITH_SHORTCUT_CLASS_NAME,
NodeActionsMenuAbout,
NodeActionsMenuItemContent,
@ -64,8 +65,7 @@ export function NodeActionsDropdownContent(props: NodeActionsMenuProps) {
{hasDeleteGroup && (
<DropdownMenuGroup>
<DropdownMenuItem
variant="destructive"
className={NODE_ACTIONS_MENU_ITEM_WITH_SHORTCUT_CLASS_NAME}
className={NODE_ACTIONS_MENU_DELETE_ITEM_CLASS_NAME}
onClick={model.handleDelete}
>
<NodeActionsMenuItemContent shortcut="workflow.delete">

View File

@ -5,6 +5,7 @@ import { ShortcutKbd } from '@/app/components/workflow/shortcuts/shortcut-kbd'
export const NODE_ACTIONS_MENU_WIDTH_CLASS_NAME = 'w-[240px] rounded-lg'
export const NODE_ACTIONS_MENU_ITEM_WITH_SHORTCUT_CLASS_NAME = 'w-auto justify-between gap-4'
export const NODE_ACTIONS_MENU_DELETE_ITEM_CLASS_NAME = `${NODE_ACTIONS_MENU_ITEM_WITH_SHORTCUT_CLASS_NAME} text-text-secondary data-highlighted:bg-state-destructive-hover data-highlighted:text-text-destructive`
export function NodeActionsMenuItemContent({
children,

View File

@ -17,9 +17,6 @@ import Item from './class-item'
const i18nPrefix = 'nodes.questionClassifiers'
// Layout constants
const HANDLE_SIDE_WIDTH = 3 // Width offset for drag handle spacing
type Props = {
nodeId: string
list: Topic[]
@ -107,7 +104,7 @@ const ClassList: FC<Props> = ({
{!collapsed && (
<div
ref={listContainerRef}
className={cn('overflow-y-visible', `pl-${HANDLE_SIDE_WIDTH}`)}
className="overflow-y-visible pl-3"
>
<ReactSortable
list={list.map(item => ({ ...item }))}
@ -130,8 +127,7 @@ const ClassList: FC<Props> = ({
<div
key={item.id}
className={cn(
'group relative rounded-[10px] bg-components-panel-bg',
`-ml-${HANDLE_SIDE_WIDTH} min-h-[40px] px-0 py-0`,
'group relative -ml-3 min-h-[40px] rounded-[10px] bg-components-panel-bg px-0 py-0',
)}
style={{
// Performance hint for browser

View File

@ -64,7 +64,6 @@ const LocaleLayout = async ({
defaultTheme="system"
enableSystem
disableTransitionOnChange
enableColorScheme={false}
>
<NuqsAdapter>
<TanstackQueryInitializer>

View File

@ -1,79 +1,12 @@
@import './preflight.css' layer(base);
@import './tailwind-core.css';
@import '@langgenius/dify-ui/styles.css';
@import '../../themes/manual-light.css' layer(base);
@import '../../themes/manual-dark.css' layer(base);
@import './monaco-sticky-fix.css' layer(base);
@import '../components/base/action-button/index.css';
@import '../components/base/badge/index.css';
@import '../components/base/premium-badge/index.css';
@import '../components/base/segmented-control/index.css';
@import 'tailwindcss';
@config '../../tailwind.config.ts';
/*
The default border color has changed to `currentcolor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}
@layer components {
html {
color-scheme: light;
}
html[data-theme='dark'] {
color-scheme: dark;
}
html[data-changing-theme] * {
transition: none !important;
}
[class*='code-'] {
@apply font-mono;
}
.text-gradient {
background: linear-gradient(91.58deg, #2250f2 -29.55%, #0ebcf3 75.22%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}
[data-theme='dark'] [data-hide-on-theme='dark'],
[data-theme='light'] [data-hide-on-theme='light'] {
display: none;
}
/* Shiki code block line numbers */
.shiki-line-numbers code {
counter-reset: line;
}
.shiki-line-numbers .line::before {
counter-increment: line;
content: counter(line);
display: inline-block;
width: 1rem;
margin-right: 0.75rem;
text-align: right;
color: var(--color-text-quaternary);
user-select: none;
}
}
@source '../../app';
@source '../../context';
@source '../../hooks';
@source '../../../packages/dify-ui/src';
@source '../../node_modules/streamdown/dist';
@source '../../node_modules/@streamdown/math/dist';
@source not '../../**/*.{spec,test}.{js,ts,jsx,tsx}';
@source not '../../**/*.stories.{js,ts,jsx,tsx}';
@source not '../../../packages/dify-ui/src/**/*.{spec,test}.{ts,tsx}';
@source not '../../../packages/dify-ui/src/**/*.stories.{ts,tsx}';

View File

@ -1,15 +1,13 @@
/* Ensures Monaco sticky header and other sticky headers remain visible in dark mode */
html[data-theme="dark"] .monaco-editor .sticky-widget {
background-color: var(--color-components-sticky-header-bg) !important;
border-bottom: 1px solid var(--color-components-sticky-header-border) !important;
background-color: var(--color-monaco-sticky-header-bg) !important;
border-bottom: 1px solid var(--color-monaco-sticky-header-border) !important;
box-shadow: var(--vscode-editorStickyScroll-shadow) 0 4px 2px -2px !important;
}
html[data-theme="dark"] .monaco-editor .sticky-line-content:hover {
background-color: var(--color-components-sticky-header-bg-hover) !important;
background-color: var(--color-monaco-sticky-header-bg-hover) !important;
}
/* Monaco editor specific sticky scroll styles in dark mode */
html[data-theme="dark"] .monaco-editor .sticky-line-root {
background-color: var(--color-components-sticky-header-bg) !important;
}
background-color: var(--color-monaco-sticky-header-bg) !important;
}

View File

@ -0,0 +1,21 @@
/*
* Pre-bound icons plugin used by `web/`. Combines Iconify's heroicons and
* remix icon packs with the project's custom public and vendor sprites.
* Wired into Tailwind v4 via `@plugin './plugins/icons.ts';` in tailwind-core.css.
*/
import { icons as customPublicIcons } from '@dify/iconify-collections/custom-public'
import { icons as customVenderIcons } from '@dify/iconify-collections/custom-vender'
import { getIconCollections, iconsPlugin } from '@egoist/tailwindcss-icons'
export default iconsPlugin({
collections: {
...getIconCollections(['heroicons', 'ri']),
'custom-public': customPublicIcons,
'custom-vender': customVenderIcons,
},
extraProperties: {
width: '1rem',
height: '1rem',
display: 'block',
},
})

View File

@ -0,0 +1,17 @@
/*
* `@tailwindcss/typography` configured with Dify's prose color tokens.
* Injects `theme.typography` for v4 CSS-first via plugin `config` merge.
*/
import typographyPlugin from '@tailwindcss/typography'
import typographyConfig from './typography-config.js'
const created = typographyPlugin()
export default {
handler: created.handler,
config: {
theme: {
typography: typographyConfig,
},
},
}

View File

@ -0,0 +1,141 @@
/*
* Tailwind CSS v4 shared core for `web/`. CSS-first: no tailwind.config.ts.
*
* Layers, JS plugins, project-only design tokens, and app-level CSS are
* declared here. Environment-specific entry files declare source scanning.
*/
@layer theme, base, components, utilities;
/* Tailwind core selective layer imports skip preflight; we ship our own
* (see ./preflight.css) so cross-app baseline stays controlled. */
@import 'tailwindcss/theme.css' layer(theme);
@import 'tailwindcss/utilities.css' layer(utilities);
/* Local preflight (replaces v3 `corePlugins.preflight: false`). */
@import './preflight.css' layer(base);
/* Design system: palette overrides, semantic tokens, light/dark themes,
* project utilities and components. */
@import '@langgenius/dify-ui/styles.css';
/* Project-only runtime CSS variables (gradients and special masks). */
@import '../../themes/manual-light.css' layer(base);
@import '../../themes/manual-dark.css' layer(base);
@import './monaco-sticky-fix.css' layer(base);
/* Component CSS using @apply / @utility. */
@import '../components/base/action-button/index.css';
@import '../components/base/badge/index.css';
@import '../components/base/premium-badge/index.css';
@import '../components/base/segmented-control/index.css';
/* ---------- JS plugins ------------------------------------------------ */
@plugin './plugins/icons.ts';
@plugin './plugins/typography.ts';
/* ---------- Project-only theme tokens --------------------------------- */
@theme {
/* Additional breakpoints layered on top of v4 defaults. */
--breakpoint-mobile: 100px;
--breakpoint-tablet: 640px;
--breakpoint-pc: 769px;
--breakpoint-2k: 2560px;
/* Custom animations. */
--animate-spin-slow: spin 2s linear infinite;
}
/* Background-image / gradient utilities. Values resolve at runtime from
* manual-light.css / manual-dark.css. Using @theme inline so the variable
* indirection survives without re-declaring values at :root. */
@theme inline {
/* Flat color (used as `bg-background-gradient-bg-fill-chat-bubble-bg-3`). */
--color-background-gradient-bg-fill-chat-bubble-bg-3: var(--color-background-gradient-bg-fill-chat-bubble-bg-3);
/* Gradients — registered under v4's --background-image-* namespace. */
--background-image-chatbot-bg: var(--color-chatbot-bg);
--background-image-chat-bubble-bg: var(--color-chat-bubble-bg);
--background-image-chat-input-mask: var(--color-chat-input-mask);
--background-image-workflow-process-bg: var(--color-workflow-process-bg);
--background-image-workflow-process-paused-bg: var(--color-workflow-process-paused-bg);
--background-image-workflow-run-failed-bg: var(--color-workflow-run-failed-bg);
--background-image-workflow-batch-failed-bg: var(--color-workflow-batch-failed-bg);
--background-image-mask-top2bottom-gray-50-to-transparent: var(--mask-top2bottom-gray-50-to-transparent);
--background-image-marketplace-divider-bg: var(--color-marketplace-divider-bg);
--background-image-marketplace-plugin-empty: var(--color-marketplace-plugin-empty);
--background-image-toast-success-bg: var(--color-toast-success-bg);
--background-image-toast-warning-bg: var(--color-toast-warning-bg);
--background-image-toast-error-bg: var(--color-toast-error-bg);
--background-image-toast-info-bg: var(--color-toast-info-bg);
--background-image-app-detail-bg: var(--color-app-detail-bg);
--background-image-app-detail-overlay-bg: var(--color-app-detail-overlay-bg);
--background-image-dataset-chunk-process-success-bg: var(--color-dataset-chunk-process-success-bg);
--background-image-dataset-chunk-process-error-bg: var(--color-dataset-chunk-process-error-bg);
--background-image-dataset-chunk-detail-card-hover-bg: var(--color-dataset-chunk-detail-card-hover-bg);
--background-image-dataset-child-chunk-expand-btn-bg: var(--color-dataset-child-chunk-expand-btn-bg);
--background-image-dataset-option-card-blue-gradient: var(--color-dataset-option-card-blue-gradient);
--background-image-dataset-option-card-purple-gradient: var(--color-dataset-option-card-purple-gradient);
--background-image-dataset-option-card-orange-gradient: var(--color-dataset-option-card-orange-gradient);
--background-image-dataset-chunk-list-mask-bg: var(--color-dataset-chunk-list-mask-bg);
--background-image-line-divider-bg: var(--color-line-divider-bg);
--background-image-dataset-warning-message-bg: var(--color-dataset-warning-message-bg);
--background-image-price-premium-badge-background: var(--color-premium-badge-background);
--background-image-premium-yearly-tip-text-background: var(--color-premium-yearly-tip-text-background);
--background-image-price-premium-text-background: var(--color-premium-text-background);
--background-image-price-enterprise-background: var(--color-price-enterprise-background);
--background-image-grid-mask-background: var(--color-grid-mask-background);
--background-image-node-data-source-bg: var(--color-node-data-source-bg);
--background-image-tag-selector-mask-bg: var(--color-tag-selector-mask-bg);
--background-image-tag-selector-mask-hover-bg: var(--color-tag-selector-mask-hover-bg);
--background-image-pipeline-template-card-hover-bg: var(--color-pipeline-template-card-hover-bg);
--background-image-pipeline-add-documents-title-bg: var(--color-pipeline-add-documents-title-bg);
--background-image-billing-plan-title-bg: var(--color-billing-plan-title-bg);
--background-image-billing-plan-card-premium-bg: var(--color-billing-plan-card-premium-bg);
--background-image-billing-plan-card-enterprise-bg: var(--color-billing-plan-card-enterprise-bg);
--background-image-knowledge-pipeline-creation-footer-bg: var(--color-knowledge-pipeline-creation-footer-bg);
--background-image-progress-bar-indeterminate-stripe: var(--color-progress-bar-indeterminate-stripe);
--background-image-chat-answer-human-input-form-divider-bg: var(--color-chat-answer-human-input-form-divider-bg);
}
/* ---------- Backwards-compat: gray-200 default border color ----------- *
* v4 changed the default border color to `currentColor`. Preserve the v3
* baseline used throughout the codebase. */
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}
/* ---------- App-level component CSS ----------------------------------- */
@layer components {
[class*='code-'] {
@apply font-mono;
}
.text-gradient {
background: linear-gradient(91.58deg, #2250f2 -29.55%, #0ebcf3 75.22%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Shiki code block line numbers */
.shiki-line-numbers code {
counter-reset: line;
}
.shiki-line-numbers .line::before {
counter-increment: line;
content: counter(line);
display: inline-block;
width: 1rem;
margin-right: 0.75rem;
text-align: right;
color: var(--color-text-quaternary);
user-select: none;
}
}

View File

@ -1,91 +0,0 @@
import { icons as customPublicIcons } from '@dify/iconify-collections/custom-public'
import { icons as customVenderIcons } from '@dify/iconify-collections/custom-vender'
import { getIconCollections, iconsPlugin } from '@egoist/tailwindcss-icons'
import difyUIPreset from '@langgenius/dify-ui/tailwind-preset'
import tailwindTypography from '@tailwindcss/typography'
import typography from './typography.js'
const config = {
presets: [difyUIPreset],
theme: {
typography,
extend: {
screens: {
'mobile': '100px',
'tablet': '640px',
'pc': '769px',
'2k': '2560px',
},
backgroundColor: {
'background-gradient-bg-fill-chat-bubble-bg-3': 'var(--color-background-gradient-bg-fill-chat-bubble-bg-3)',
},
backgroundImage: {
'chatbot-bg': 'var(--color-chatbot-bg)',
'chat-bubble-bg': 'var(--color-chat-bubble-bg)',
'chat-input-mask': 'var(--color-chat-input-mask)',
'workflow-process-bg': 'var(--color-workflow-process-bg)',
'workflow-process-paused-bg': 'var(--color-workflow-process-paused-bg)',
'workflow-run-failed-bg': 'var(--color-workflow-run-failed-bg)',
'workflow-batch-failed-bg': 'var(--color-workflow-batch-failed-bg)',
'mask-top2bottom-gray-50-to-transparent': 'var(--mask-top2bottom-gray-50-to-transparent)',
'marketplace-divider-bg': 'var(--color-marketplace-divider-bg)',
'marketplace-plugin-empty': 'var(--color-marketplace-plugin-empty)',
'toast-success-bg': 'var(--color-toast-success-bg)',
'toast-warning-bg': 'var(--color-toast-warning-bg)',
'toast-error-bg': 'var(--color-toast-error-bg)',
'toast-info-bg': 'var(--color-toast-info-bg)',
'app-detail-bg': 'var(--color-app-detail-bg)',
'app-detail-overlay-bg': 'var(--color-app-detail-overlay-bg)',
'dataset-chunk-process-success-bg': 'var(--color-dataset-chunk-process-success-bg)',
'dataset-chunk-process-error-bg': 'var(--color-dataset-chunk-process-error-bg)',
'dataset-chunk-detail-card-hover-bg': 'var(--color-dataset-chunk-detail-card-hover-bg)',
'dataset-child-chunk-expand-btn-bg': 'var(--color-dataset-child-chunk-expand-btn-bg)',
'dataset-option-card-blue-gradient': 'var(--color-dataset-option-card-blue-gradient)',
'dataset-option-card-purple-gradient': 'var(--color-dataset-option-card-purple-gradient)',
'dataset-option-card-orange-gradient': 'var(--color-dataset-option-card-orange-gradient)',
'dataset-chunk-list-mask-bg': 'var(--color-dataset-chunk-list-mask-bg)',
'line-divider-bg': 'var(--color-line-divider-bg)',
'dataset-warning-message-bg': 'var(--color-dataset-warning-message-bg)',
'price-premium-badge-background': 'var(--color-premium-badge-background)',
'premium-yearly-tip-text-background': 'var(--color-premium-yearly-tip-text-background)',
'price-premium-text-background': 'var(--color-premium-text-background)',
'price-enterprise-background': 'var(--color-price-enterprise-background)',
'grid-mask-background': 'var(--color-grid-mask-background)',
'node-data-source-bg': 'var(--color-node-data-source-bg)',
'tag-selector-mask-bg': 'var(--color-tag-selector-mask-bg)',
'tag-selector-mask-hover-bg': 'var(--color-tag-selector-mask-hover-bg)',
'pipeline-template-card-hover-bg': 'var(--color-pipeline-template-card-hover-bg)',
'pipeline-add-documents-title-bg': 'var(--color-pipeline-add-documents-title-bg)',
'billing-plan-title-bg': 'var(--color-billing-plan-title-bg)',
'billing-plan-card-premium-bg': 'var(--color-billing-plan-card-premium-bg)',
'billing-plan-card-enterprise-bg': 'var(--color-billing-plan-card-enterprise-bg)',
'knowledge-pipeline-creation-footer-bg': 'var(--color-knowledge-pipeline-creation-footer-bg)',
'progress-bar-indeterminate-stripe': 'var(--color-progress-bar-indeterminate-stripe)',
'chat-answer-human-input-form-divider-bg': 'var(--color-chat-answer-human-input-form-divider-bg)',
},
animation: {
'spin-slow': 'spin 2s linear infinite',
},
},
},
plugins: [
tailwindTypography,
iconsPlugin({
collections: {
...getIconCollections(['heroicons', 'ri']),
'custom-public': customPublicIcons,
'custom-vender': customVenderIcons,
},
extraProperties: {
width: '1rem',
height: '1rem',
display: 'block',
},
}),
],
corePlugins: {
preflight: false,
},
}
export default config

View File

@ -1,18 +0,0 @@
import type { Config } from 'tailwindcss'
import commonConfig from './tailwind-common-config'
const config: Config = {
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./context/**/*.{js,ts,jsx,tsx}',
'../packages/dify-ui/src/**/*.{ts,tsx}',
'./node_modules/streamdown/dist/*.js',
'./node_modules/@streamdown/math/dist/*.js',
'!./**/*.{spec,test}.{js,ts,jsx,tsx}',
'!../packages/dify-ui/src/**/*.{spec,test}.{ts,tsx}',
],
...commonConfig,
}
export default config

View File

@ -1,4 +1,11 @@
html[data-theme="dark"] {
--color-monaco-sticky-header-bg: var(--color-components-panel-bg);
--color-monaco-sticky-header-bg-hover: var(--color-components-panel-on-panel-item-bg-hover);
--color-monaco-sticky-header-border: var(--color-components-panel-border);
--vscode-editorStickyScroll-background: var(--color-monaco-sticky-header-bg);
--vscode-editorStickyScrollHover-background: var(--color-monaco-sticky-header-bg-hover);
--vscode-editorStickyScroll-border: var(--color-monaco-sticky-header-border);
--vscode-editorStickyScroll-shadow: rgba(0, 0, 0, 0.6);
--color-chatbot-bg: linear-gradient(180deg,
rgba(34, 34, 37, 0.9) 0%,
rgba(29, 29, 32, 0.9) 90.48%);