style(web): apply linter formatting across model config components

Normalize quote style, import ordering, and class name ordering as
reported by the project linter.
This commit is contained in:
SiYue-ZO 2026-05-06 18:16:52 +08:00
parent 77c6f31983
commit 249fa93e95
13 changed files with 213 additions and 221 deletions

View file

@ -66,10 +66,7 @@ export function WebSearchGeneralSettings({
</SettingRow> </SettingRow>
<SettingRow <SettingRow
label={t( label={t("pages.agent.tools.web_search.proxy", "Proxy Configuration")}
"pages.agent.tools.web_search.proxy",
"Proxy Configuration",
)}
description={t( description={t(
"pages.agent.tools.web_search.proxy_description", "pages.agent.tools.web_search.proxy_description",
"Optional global HTTP/S proxy for underlying web requests.", "Optional global HTTP/S proxy for underlying web requests.",

View file

@ -84,10 +84,7 @@ function ProviderCard({
const { t } = useTranslation() const { t } = useTranslation()
const apiKeyPlaceholder = maskedSecretPlaceholder( const apiKeyPlaceholder = maskedSecretPlaceholder(
settings.api_key_set ? `${providerId}-configured` : "", settings.api_key_set ? `${providerId}-configured` : "",
t( t("pages.agent.tools.web_search.api_key_placeholder", "Enter API key..."),
"pages.agent.tools.web_search.api_key_placeholder",
"Enter API key...",
),
) )
const updateSettings = ( const updateSettings = (
@ -167,7 +164,10 @@ function ProviderCard({
> >
<div className="ml-8 flex max-w-xl flex-col gap-5"> <div className="ml-8 flex max-w-xl flex-col gap-5">
<ProviderField <ProviderField
label={t("pages.agent.tools.web_search.max_results", "Max Results")} label={t(
"pages.agent.tools.web_search.max_results",
"Max Results",
)}
> >
<Input <Input
type="number" type="number"

View file

@ -128,7 +128,10 @@ export function ChatComposer({
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
{contextUsage && ( {contextUsage && (
<ContextUsageRing usage={contextUsage} onDetailClick={onContextDetail} /> <ContextUsageRing
usage={contextUsage}
onDetailClick={onContextDetail}
/>
)} )}
{canInput ? ( {canInput ? (
<Tooltip delayDuration={700}> <Tooltip delayDuration={700}>

View file

@ -127,7 +127,7 @@ export function ContextUsageRing({
: "pointer-events-none scale-95 opacity-0" : "pointer-events-none scale-95 opacity-0"
}`} }`}
> >
<div className="bg-popover absolute -bottom-1.5 right-3 h-3 w-3 rotate-45 border-r border-b" /> <div className="bg-popover absolute right-3 -bottom-1.5 h-3 w-3 rotate-45 border-r border-b" />
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className="text-muted-foreground text-xs"> <span className="text-muted-foreground text-xs">

View file

@ -545,9 +545,7 @@ export function LauncherSection({
disabled={disabled} disabled={disabled}
autoComplete="new-password" autoComplete="new-password"
placeholder={t("pages.config.dashboard_password_placeholder")} placeholder={t("pages.config.dashboard_password_placeholder")}
onChange={(e) => onChange={(e) => onFieldChange("dashboardPassword", e.target.value)}
onFieldChange("dashboardPassword", e.target.value)
}
/> />
</Field> </Field>

View file

@ -5,11 +5,10 @@
* Messages use i18n keys with interpolation params callers must * Messages use i18n keys with interpolation params callers must
* translate them via t(key, params). * translate them via t(key, params).
*/ */
import { import {
findClosestProvider,
KNOWN_PROVIDER_KEYS, KNOWN_PROVIDER_KEYS,
PROVIDER_ALIASES, PROVIDER_ALIASES,
findClosestProvider,
} from "./provider-registry" } from "./provider-registry"
export type ValidationLevel = "error" | "warning" | "success" export type ValidationLevel = "error" | "warning" | "success"

View file

@ -1,4 +1,9 @@
import { IconDatabase, IconLoader2, IconPlus, IconStar } from "@tabler/icons-react" import {
IconDatabase,
IconLoader2,
IconPlus,
IconStar,
} from "@tabler/icons-react"
import { useCallback, useEffect, useState } from "react" import { useCallback, useEffect, useState } from "react"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import { toast } from "sonner" import { toast } from "sonner"

View file

@ -63,10 +63,13 @@ export function ProviderCombobox({
} }
return ( return (
<Popover open={open} onOpenChange={(v) => { <Popover
setOpen(v) open={open}
if (!v) setCustomMode(false) onOpenChange={(v) => {
}}> setOpen(v)
if (!v) setCustomMode(false)
}}
>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<Button <Button
variant="outline" variant="outline"

View file

@ -1,9 +1,6 @@
import { useMemo, useState } from "react" import { useMemo, useState } from "react"
import { import { PROVIDER_DOMAINS, PROVIDER_ICON_SLUGS } from "./provider-registry"
PROVIDER_DOMAINS,
PROVIDER_ICON_SLUGS,
} from "./provider-registry"
interface ProviderIconProps { interface ProviderIconProps {
providerKey: string providerKey: string

View file

@ -1,7 +1,4 @@
import { import { PROVIDER_ALIASES, PROVIDER_LABELS } from "./provider-registry"
PROVIDER_ALIASES,
PROVIDER_LABELS,
} from "./provider-registry"
export function getProviderKey(provider?: string): string { export function getProviderKey(provider?: string): string {
const normalized = provider?.trim().toLowerCase() const normalized = provider?.trim().toLowerCase()

View file

@ -20,344 +20,334 @@ export interface ProviderDefinition {
export const PROVIDERS: ProviderDefinition[] = [ export const PROVIDERS: ProviderDefinition[] = [
{ {
key: 'openai', key: "openai",
label: 'OpenAI', label: "OpenAI",
iconSlug: 'openai', iconSlug: "openai",
domain: 'openai.com', domain: "openai.com",
defaultApiBase: 'https://api.openai.com/v1', defaultApiBase: "https://api.openai.com/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 100, priority: 100,
commonModels: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1', 'o3-mini'], commonModels: ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "o1", "o3-mini"],
aliases: ['gpt'], aliases: ["gpt"],
}, },
{ {
key: 'anthropic', key: "anthropic",
label: 'Anthropic', label: "Anthropic",
iconSlug: 'anthropic', iconSlug: "anthropic",
domain: 'anthropic.com', domain: "anthropic.com",
defaultApiBase: 'https://api.anthropic.com/v1', defaultApiBase: "https://api.anthropic.com/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 95, priority: 95,
commonModels: [ commonModels: [
'claude-sonnet-4-20250514', "claude-sonnet-4-20250514",
'claude-haiku-4-20250414', "claude-haiku-4-20250414",
'claude-3-5-sonnet-20241022', "claude-3-5-sonnet-20241022",
], ],
aliases: ['claude'], aliases: ["claude"],
}, },
{ {
key: 'gemini', key: "gemini",
label: 'Google Gemini', label: "Google Gemini",
iconSlug: 'googlegemini', iconSlug: "googlegemini",
domain: 'gemini.google.com', domain: "gemini.google.com",
defaultApiBase: 'https://generativelanguage.googleapis.com/v1beta', defaultApiBase: "https://generativelanguage.googleapis.com/v1beta",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 90, priority: 90,
commonModels: ['gemini-2.0-flash', 'gemini-2.5-pro', 'gemini-1.5-flash'], commonModels: ["gemini-2.0-flash", "gemini-2.5-pro", "gemini-1.5-flash"],
aliases: ['google'], aliases: ["google"],
}, },
{ {
key: 'deepseek', key: "deepseek",
label: 'DeepSeek', label: "DeepSeek",
iconSlug: 'deepseek', iconSlug: "deepseek",
domain: 'deepseek.com', domain: "deepseek.com",
defaultApiBase: 'https://api.deepseek.com/v1', defaultApiBase: "https://api.deepseek.com/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 85, priority: 85,
commonModels: ['deepseek-chat', 'deepseek-reasoner'], commonModels: ["deepseek-chat", "deepseek-reasoner"],
}, },
{ {
key: 'openrouter', key: "openrouter",
label: 'OpenRouter', label: "OpenRouter",
iconSlug: 'openrouter', iconSlug: "openrouter",
domain: 'openrouter.ai', domain: "openrouter.ai",
defaultApiBase: 'https://openrouter.ai/api/v1', defaultApiBase: "https://openrouter.ai/api/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 80, priority: 80,
commonModels: [ commonModels: [
'openai/gpt-4o', "openai/gpt-4o",
'anthropic/claude-sonnet-4', "anthropic/claude-sonnet-4",
'google/gemini-2.0-flash', "google/gemini-2.0-flash",
], ],
}, },
{ {
key: 'qwen-portal', key: "qwen-portal",
label: 'Qwen', label: "Qwen",
labelZh: 'Qwen (阿里云)', labelZh: "Qwen (阿里云)",
iconSlug: 'alibabacloud', iconSlug: "alibabacloud",
domain: 'qwenlm.ai', domain: "qwenlm.ai",
defaultApiBase: defaultApiBase: "https://dashscope.aliyuncs.com/compatible-mode/v1",
'https://dashscope.aliyuncs.com/compatible-mode/v1',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 75, priority: 75,
commonModels: ['qwen-max', 'qwen-plus', 'qwen-turbo'], commonModels: ["qwen-max", "qwen-plus", "qwen-turbo"],
aliases: ['qwen'], aliases: ["qwen"],
}, },
{ {
key: 'qwen-intl', key: "qwen-intl",
label: 'Qwen International', label: "Qwen International",
iconSlug: 'alibabacloud', iconSlug: "alibabacloud",
domain: 'alibabacloud.com', domain: "alibabacloud.com",
defaultApiBase: defaultApiBase: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 74, priority: 74,
commonModels: ['qwen-max', 'qwen-plus', 'qwen-turbo'], commonModels: ["qwen-max", "qwen-plus", "qwen-turbo"],
aliases: ['qwen-international', 'dashscope-intl'], aliases: ["qwen-international", "dashscope-intl"],
}, },
{ {
key: 'moonshot', key: "moonshot",
label: 'Moonshot', label: "Moonshot",
labelZh: 'Moonshot (月之暗面)', labelZh: "Moonshot (月之暗面)",
domain: 'moonshot.ai', domain: "moonshot.ai",
defaultApiBase: 'https://api.moonshot.cn/v1', defaultApiBase: "https://api.moonshot.cn/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 70, priority: 70,
commonModels: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'], commonModels: ["moonshot-v1-8k", "moonshot-v1-32k", "moonshot-v1-128k"],
}, },
{ {
key: 'volcengine', key: "volcengine",
label: 'Volcengine', label: "Volcengine",
labelZh: 'Volcengine (火山引擎)', labelZh: "Volcengine (火山引擎)",
iconSlug: 'bytedance', iconSlug: "bytedance",
domain: 'volcengine.com', domain: "volcengine.com",
defaultApiBase: defaultApiBase: "https://ark.cn-beijing.volces.com/api/v3",
'https://ark.cn-beijing.volces.com/api/v3',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 69, priority: 69,
commonModels: ['doubao-1.5-pro', 'doubao-1.5-lite'], commonModels: ["doubao-1.5-pro", "doubao-1.5-lite"],
}, },
{ {
key: 'zhipu', key: "zhipu",
label: 'Zhipu AI', label: "Zhipu AI",
labelZh: 'Zhipu AI (智谱)', labelZh: "Zhipu AI (智谱)",
iconSlug: 'zhipu', iconSlug: "zhipu",
domain: 'zhipuai.cn', domain: "zhipuai.cn",
defaultApiBase: defaultApiBase: "https://open.bigmodel.cn/api/paas/v4",
'https://open.bigmodel.cn/api/paas/v4',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 68, priority: 68,
commonModels: ['glm-4-plus', 'glm-4-flash'], commonModels: ["glm-4-plus", "glm-4-flash"],
}, },
{ {
key: 'groq', key: "groq",
label: 'Groq', label: "Groq",
iconSlug: 'groq', iconSlug: "groq",
domain: 'groq.com', domain: "groq.com",
defaultApiBase: 'https://api.groq.com/openai/v1', defaultApiBase: "https://api.groq.com/openai/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 65, priority: 65,
commonModels: [ commonModels: ["llama-3.3-70b-versatile", "mixtral-8x7b-32768"],
'llama-3.3-70b-versatile',
'mixtral-8x7b-32768',
],
}, },
{ {
key: 'mistral', key: "mistral",
label: 'Mistral AI', label: "Mistral AI",
iconSlug: 'mistralai', iconSlug: "mistralai",
domain: 'mistral.ai', domain: "mistral.ai",
defaultApiBase: 'https://api.mistral.ai/v1', defaultApiBase: "https://api.mistral.ai/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 64, priority: 64,
commonModels: ['mistral-large-latest', 'mistral-small-latest'], commonModels: ["mistral-large-latest", "mistral-small-latest"],
}, },
{ {
key: 'nvidia', key: "nvidia",
label: 'NVIDIA', label: "NVIDIA",
iconSlug: 'nvidia', iconSlug: "nvidia",
domain: 'nvidia.com', domain: "nvidia.com",
defaultApiBase: defaultApiBase: "https://integrate.api.nvidia.com/v1",
'https://integrate.api.nvidia.com/v1',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 63, priority: 63,
commonModels: ['meta/llama-3.1-405b-instruct'], commonModels: ["meta/llama-3.1-405b-instruct"],
}, },
{ {
key: 'cerebras', key: "cerebras",
label: 'Cerebras', label: "Cerebras",
iconSlug: 'cerebras', iconSlug: "cerebras",
domain: 'cerebras.ai', domain: "cerebras.ai",
defaultApiBase: 'https://api.cerebras.ai/v1', defaultApiBase: "https://api.cerebras.ai/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 62, priority: 62,
commonModels: ['llama3.1-8b', 'llama3.1-70b'], commonModels: ["llama3.1-8b", "llama3.1-70b"],
}, },
{ {
key: 'azure', key: "azure",
label: 'Azure OpenAI', label: "Azure OpenAI",
iconSlug: 'microsoftazure', iconSlug: "microsoftazure",
domain: 'azure.com', domain: "azure.com",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 61, priority: 61,
commonModels: ['gpt-4o', 'gpt-4o-mini'], commonModels: ["gpt-4o", "gpt-4o-mini"],
}, },
{ {
key: 'github-copilot', key: "github-copilot",
label: 'GitHub Copilot', label: "GitHub Copilot",
iconSlug: 'githubcopilot', iconSlug: "githubcopilot",
domain: 'github.com', domain: "github.com",
requiresApiKey: false, requiresApiKey: false,
isLocal: true, isLocal: true,
priority: 55, priority: 55,
}, },
{ {
key: 'antigravity', key: "antigravity",
label: 'Google Code Assist', label: "Google Code Assist",
domain: 'antigravity.google', domain: "antigravity.google",
requiresApiKey: false, requiresApiKey: false,
isLocal: false, isLocal: false,
priority: 54, priority: 54,
}, },
{ {
key: 'ollama', key: "ollama",
label: 'Ollama', label: "Ollama",
labelZh: 'Ollama (本地)', labelZh: "Ollama (本地)",
iconSlug: 'ollama', iconSlug: "ollama",
domain: 'ollama.com', domain: "ollama.com",
defaultApiBase: 'http://localhost:11434/v1', defaultApiBase: "http://localhost:11434/v1",
requiresApiKey: false, requiresApiKey: false,
isLocal: true, isLocal: true,
priority: 50, priority: 50,
commonModels: ['llama3', 'mistral', 'codellama', 'qwen2.5'], commonModels: ["llama3", "mistral", "codellama", "qwen2.5"],
}, },
{ {
key: 'vllm', key: "vllm",
label: 'VLLM', label: "VLLM",
labelZh: 'VLLM (本地)', labelZh: "VLLM (本地)",
domain: 'vllm.ai', domain: "vllm.ai",
defaultApiBase: 'http://localhost:8000/v1', defaultApiBase: "http://localhost:8000/v1",
requiresApiKey: false, requiresApiKey: false,
isLocal: true, isLocal: true,
priority: 49, priority: 49,
}, },
{ {
key: 'lmstudio', key: "lmstudio",
label: 'LM Studio', label: "LM Studio",
labelZh: 'LM Studio (本地)', labelZh: "LM Studio (本地)",
domain: 'lmstudio.ai', domain: "lmstudio.ai",
defaultApiBase: 'http://localhost:1234/v1', defaultApiBase: "http://localhost:1234/v1",
requiresApiKey: false, requiresApiKey: false,
isLocal: true, isLocal: true,
priority: 48, priority: 48,
}, },
{ {
key: 'venice', key: "venice",
label: 'Venice AI', label: "Venice AI",
iconSlug: 'venice', iconSlug: "venice",
domain: 'venice.ai', domain: "venice.ai",
defaultApiBase: 'https://api.venice.ai/api/v1', defaultApiBase: "https://api.venice.ai/api/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 45, priority: 45,
}, },
{ {
key: 'shengsuanyun', key: "shengsuanyun",
label: 'ShengsuanYun', label: "ShengsuanYun",
labelZh: 'ShengsuanYun (神算云)', labelZh: "ShengsuanYun (神算云)",
domain: 'shengsuanyun.com', domain: "shengsuanyun.com",
defaultApiBase: defaultApiBase: "https://router.shengsuanyun.com/api/v1",
'https://router.shengsuanyun.com/api/v1',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 44, priority: 44,
}, },
{ {
key: 'vivgrid', key: "vivgrid",
label: 'Vivgrid', label: "Vivgrid",
domain: 'vivgrid.com', domain: "vivgrid.com",
defaultApiBase: 'https://api.vivgrid.com/v1', defaultApiBase: "https://api.vivgrid.com/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 43, priority: 43,
}, },
{ {
key: 'minimax', key: "minimax",
label: 'MiniMax', label: "MiniMax",
domain: 'minimaxi.com', domain: "minimaxi.com",
defaultApiBase: 'https://api.minimaxi.com/v1', defaultApiBase: "https://api.minimaxi.com/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 42, priority: 42,
}, },
{ {
key: 'longcat', key: "longcat",
label: 'LongCat', label: "LongCat",
domain: 'longcat.chat', domain: "longcat.chat",
defaultApiBase: 'https://api.longcat.chat/openai', defaultApiBase: "https://api.longcat.chat/openai",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 41, priority: 41,
}, },
{ {
key: 'modelscope', key: "modelscope",
label: 'ModelScope', label: "ModelScope",
labelZh: 'ModelScope (魔搭社区)', labelZh: "ModelScope (魔搭社区)",
domain: 'modelscope.cn', domain: "modelscope.cn",
defaultApiBase: defaultApiBase: "https://api-inference.modelscope.cn/v1",
'https://api-inference.modelscope.cn/v1',
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 40, priority: 40,
}, },
{ {
key: 'mimo', key: "mimo",
label: 'Xiaomi MiMo', label: "Xiaomi MiMo",
iconSlug: 'xiaomi', iconSlug: "xiaomi",
domain: 'xiaomi.com', domain: "xiaomi.com",
defaultApiBase: 'https://api.xiaomimimo.com/v1', defaultApiBase: "https://api.xiaomimimo.com/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 39, priority: 39,
}, },
{ {
key: 'avian', key: "avian",
label: 'Avian', label: "Avian",
domain: 'avian.io', domain: "avian.io",
defaultApiBase: 'https://api.avian.io/v1', defaultApiBase: "https://api.avian.io/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 38, priority: 38,
}, },
{ {
key: 'zai', key: "zai",
label: 'Z.ai', label: "Z.ai",
domain: 'z.ai', domain: "z.ai",
defaultApiBase: 'https://api.z.ai/api/coding/paas/v4', defaultApiBase: "https://api.z.ai/api/coding/paas/v4",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 37, priority: 37,
aliases: ['z.ai', 'z-ai'], aliases: ["z.ai", "z-ai"],
}, },
{ {
key: 'novita', key: "novita",
label: 'Novita AI', label: "Novita AI",
domain: 'novita.ai', domain: "novita.ai",
defaultApiBase: 'https://api.novita.ai/openai', defaultApiBase: "https://api.novita.ai/openai",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 36, priority: 36,
}, },
{ {
key: 'litellm', key: "litellm",
label: 'LiteLLM', label: "LiteLLM",
domain: 'litellm.ai', domain: "litellm.ai",
defaultApiBase: 'http://localhost:4000/v1', defaultApiBase: "http://localhost:4000/v1",
requiresApiKey: true, requiresApiKey: true,
isLocal: false, isLocal: false,
priority: 35, priority: 35,
@ -373,9 +363,7 @@ export const PROVIDER_LABELS: Record<string, string> = Object.fromEntries(
) )
export const PROVIDER_ALIASES: Record<string, string> = Object.fromEntries( export const PROVIDER_ALIASES: Record<string, string> = Object.fromEntries(
PROVIDERS.flatMap((p) => PROVIDERS.flatMap((p) => (p.aliases || []).map((a) => [a, p.key])),
(p.aliases || []).map((a) => [a, p.key]),
),
) )
export const KNOWN_PROVIDER_KEYS = new Set(PROVIDERS.map((p) => p.key)) export const KNOWN_PROVIDER_KEYS = new Set(PROVIDERS.map((p) => p.key))

View file

@ -93,7 +93,12 @@ interface KeyInputProps {
className?: string className?: string
} }
export function KeyInput({ value, onChange, placeholder, className }: KeyInputProps) { export function KeyInput({
value,
onChange,
placeholder,
className,
}: KeyInputProps) {
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
return ( return (

View file

@ -1,7 +1,6 @@
import { useEffect } from "react"
import githubDarkCss from "highlight.js/styles/github-dark.css?inline" import githubDarkCss from "highlight.js/styles/github-dark.css?inline"
import githubLightCss from "highlight.js/styles/github.css?inline" import githubLightCss from "highlight.js/styles/github.css?inline"
import { useEffect } from "react"
const THEME_STYLE_ID = "hljs-theme-style" const THEME_STYLE_ID = "hljs-theme-style"
const THEME_STYLE_OWNER_ATTR = "data-picoclaw-highlight-theme" const THEME_STYLE_OWNER_ATTR = "data-picoclaw-highlight-theme"
@ -17,8 +16,9 @@ function getOrCreateThemeStyleElement(): HTMLStyleElement {
return managedStyleElement return managedStyleElement
} }
const existingStyleElement = const existingStyleElement = document.querySelector<HTMLStyleElement>(
document.querySelector<HTMLStyleElement>(ID_THEME_STYLE_SELECTOR) ID_THEME_STYLE_SELECTOR,
)
if (existingStyleElement) { if (existingStyleElement) {
existingStyleElement.setAttribute( existingStyleElement.setAttribute(
THEME_STYLE_OWNER_ATTR, THEME_STYLE_OWNER_ATTR,