diff --git a/CHANGELOG.md b/CHANGELOG.md index a172b16b..2d38aa49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ ## [Unreleased] +### Added + +- **主题与外观** + - 深色 / 浅色主题切换:可选浅色、深色或跟随系统,界面即时切换、重启保留。 + - 编辑器配色主题:内置多款可选(VS Code 2026 / Modern、高对比,以及 GitHub、Monokai、Dracula、Nord、Solarized 等),可跟随应用主题或单独指定。 + - 编辑器字体与字号:自定义等宽字体(可多个候选)与字号,编辑器及全应用等宽文本(diff / 评论 / 代码块)一并生效。 + ### Changed - 配置面板改为左右分区布局:左侧分区导航(常规 / 连接 / AI / 关于)、右侧按分区归类展示配置项,替代此前单列平铺;分区结构为后续扩展(主题、编辑器风格、上下文窗口等)预留。 diff --git a/apps/desktop/src/main/controllers/config.ts b/apps/desktop/src/main/controllers/config.ts index 8fb9085c..8d856829 100644 --- a/apps/desktop/src/main/controllers/config.ts +++ b/apps/desktop/src/main/controllers/config.ts @@ -39,6 +39,43 @@ export const setLanguage: IpcController<'config:setLanguage'> = async (_event, r logger.info({ language: req.language }, 'language config updated'); }; +/** + * 写 GUI 主题偏好;内存同步。纯前端展示项,主进程无副作用(不切 i18n、不重建 adapter)。 + */ +export const setTheme: IpcController<'config:setTheme'> = async (_event, req) => { + const { bootstrap, logger } = getContext(); + const appearance = { ...bootstrap.config.appearance, theme: req.theme }; + await writeConfig(bootstrap.paths.configFile, { ...bootstrap.config, appearance }); + bootstrap.config.appearance = appearance; + logger.info({ theme: req.theme }, 'theme preference updated'); +}; + +/** + * 写编辑器外观(Monaco 主题 + 等宽字体);内存同步。纯前端展示项,主进程无副作用。 + */ +export const setEditorAppearance: IpcController<'config:setEditorAppearance'> = async ( + _event, + req, +) => { + const { bootstrap, logger } = getContext(); + const appearance = { + ...bootstrap.config.appearance, + editor_theme: req.editor_theme, + editor_font_family: req.editor_font_family, + editor_font_size: req.editor_font_size, + }; + await writeConfig(bootstrap.paths.configFile, { ...bootstrap.config, appearance }); + bootstrap.config.appearance = appearance; + logger.info( + { + editorTheme: req.editor_theme, + editorFontFamily: req.editor_font_family, + editorFontSize: req.editor_font_size, + }, + 'editor appearance updated', + ); +}; + /** * 写 LLM Provider 配置;内存同步,下次 pragent:run 用新值。 */ diff --git a/apps/desktop/src/main/ipc.ts b/apps/desktop/src/main/ipc.ts index 16af4616..63eef70a 100644 --- a/apps/desktop/src/main/ipc.ts +++ b/apps/desktop/src/main/ipc.ts @@ -94,6 +94,8 @@ export function registerIpcHandlers(deps: RegisterDeps): { ipcMain.handle('config:read', config.readConfig); // 读当前内存配置 ipcMain.handle('config:setReposDir', config.setReposDir); // 设仓库目录(重启生效) ipcMain.handle('config:setLanguage', config.setLanguage); // 设 UI 语言(热生效) + ipcMain.handle('config:setTheme', config.setTheme); // 设 GUI 主题偏好(前端即时生效) + ipcMain.handle('config:setEditorAppearance', config.setEditorAppearance); // 设编辑器主题 + 字体(前端即时生效) ipcMain.handle('config:setLlm', config.setLlm); // 设 LLM Provider 配置 ipcMain.handle('config:setAgent', config.setAgent); // 设 Agent 配置(含 agent.dir) ipcMain.handle('agent:setAutopilotEnabled', config.setAutopilotEnabled); // AutoPilot 开关 diff --git a/apps/desktop/src/renderer/src/App.tsx b/apps/desktop/src/renderer/src/App.tsx index 850d94ee..3a69f3eb 100644 --- a/apps/desktop/src/renderer/src/App.tsx +++ b/apps/desktop/src/renderer/src/App.tsx @@ -16,6 +16,7 @@ import { usePanelLayout } from './hooks/usePanelLayout'; import { useUpdateNotice } from './hooks/useUpdateNotice'; import { useAppStores } from './hooks/useAppStores'; import { useExternalLinkGuard } from './hooks/useExternalLinkGuard'; +import { useTheme, useEditorAppearanceSync } from './hooks/useTheme'; export default function App() { const { t } = useTranslation(); @@ -51,6 +52,18 @@ export default function App() { const updateInfo = useUpdateNotice(); useAppStores(); useExternalLinkGuard(); + // GUI 主题:跟随 config 偏好生效('system' 下还跟随 OS 切换)。boot 前用默认深色,模块导入时已按 + // localStorage 缓存定下首帧主题,boot 到达后切到 config 偏好。 + useTheme(boot?.config.appearance.theme ?? 'dark'); + // 编辑器外观(Monaco 主题 + 等宽字体):跟随 config 同步到运行时 store + 字体 CSS 变量。 + useEditorAppearanceSync( + boot?.config.appearance ?? { + theme: 'dark', + editor_theme: 'auto', + editor_font_family: '', + editor_font_size: 14, + }, + ); const [showSettings, setShowSettings] = useState(false); /** @@ -195,6 +208,12 @@ export default function App() { onLlmChange={(llm) => patchConfig((c) => ({ ...c, llm }))} onProxyChange={(proxy) => patchConfig((c) => ({ ...c, proxy }))} onLanguageChange={(language) => patchConfig((c) => ({ ...c, language }))} + onThemeChange={(theme) => + patchConfig((c) => ({ ...c, appearance: { ...c.appearance, theme } })) + } + onEditorAppearanceChange={(appearance) => + patchConfig((c) => ({ ...c, appearance: { ...c.appearance, ...appearance } })) + } onConnectionsChange={refreshBootAndPrs} onClose={() => setShowSettings(false)} /> diff --git a/apps/desktop/src/renderer/src/components/common/MermaidDiagram.tsx b/apps/desktop/src/renderer/src/components/common/MermaidDiagram.tsx index 001e3acf..70741e08 100644 --- a/apps/desktop/src/renderer/src/components/common/MermaidDiagram.tsx +++ b/apps/desktop/src/renderer/src/components/common/MermaidDiagram.tsx @@ -1,6 +1,7 @@ import { useEffect, useId, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; +import { useResolvedTheme } from '../../hooks/useTheme'; /** * Mermaid 渲染:把 ```mermaid 代码块渲染成 SVG 图(Qodo `/describe` 常生成架构图)。 @@ -10,7 +11,8 @@ import { useTranslation } from 'react-i18next'; * - **securityLevel: 'strict'**:内容来自 AI / 远端 PR 描述,strict 下 mermaid 转义 * 标签文本、禁用点击脚本,产出的 SVG 可安全注入。 * - **失败回退**:语法错 / 渲染异常时回退展示原始代码块,图画错也能看源码。 - * - 主题 `dark`,与应用深色界面一致。 + * - 主题随应用深 / 浅色切换(`dark` / `default`):mermaid 主题为全局态、不走 CSS 自定义属性, + * 故每次渲染前按当前解析主题 re-initialize,并把主题纳入渲染 effect 依赖、切换时重绘。 */ // 仅声明本组件用到的最小接口,避免 import() 类型注解(且与 mermaid 内部类型解耦)。 @@ -26,7 +28,8 @@ function loadMermaid(): Promise { mermaidLoader ??= import('mermaid') .then((m) => { const mermaid = m.default as unknown as MermaidApi; - mermaid.initialize({ startOnLoad: false, theme: 'dark', securityLevel: 'strict' }); + // 主题不在此固定:每次渲染前按当前应用主题 re-initialize(见组件渲染 effect)。 + mermaid.initialize({ startOnLoad: false, securityLevel: 'strict' }); return mermaid; }) .catch((e: unknown) => { @@ -38,6 +41,8 @@ function loadMermaid(): Promise { export function MermaidDiagram({ source }: { source: string }) { const { t } = useTranslation(); + // mermaid 主题为全局态、不走 CSS 自定义属性:随应用解析主题切换(深 'dark' / 浅 'default')。 + const mermaidTheme = useResolvedTheme() === 'light' ? 'default' : 'dark'; // mermaid.render 需要唯一 id(内部建临时 DOM 节点);useId 保证每个实例稳定唯一, // 去掉 `:`(mermaid 用作 DOM id / CSS 选择器,冒号非法) const renderId = `mmd-${useId().replace(/:/g, '')}`; @@ -52,6 +57,8 @@ export function MermaidDiagram({ source }: { source: string }) { void (async () => { try { const mermaid = await loadMermaid(); + // 渲染前按当前主题 re-initialize(全局态,幂等):主题切换后重渲即换配色。 + mermaid.initialize({ startOnLoad: false, theme: mermaidTheme, securityLevel: 'strict' }); const out = await mermaid.render(renderId, source); if (!cancelled) setSvg(out.svg); } catch (e) { @@ -63,7 +70,7 @@ export function MermaidDiagram({ source }: { source: string }) { return () => { cancelled = true; }; - }, [source, renderId]); + }, [source, renderId, mermaidTheme]); if (failed) { // 回退:保留原始 mermaid 源码,至少可读 diff --git a/apps/desktop/src/renderer/src/components/features/pr/tabs/comments/InlineCodeContext.tsx b/apps/desktop/src/renderer/src/components/features/pr/tabs/comments/InlineCodeContext.tsx index 8c5a058c..b291f2df 100644 --- a/apps/desktop/src/renderer/src/components/features/pr/tabs/comments/InlineCodeContext.tsx +++ b/apps/desktop/src/renderer/src/components/features/pr/tabs/comments/InlineCodeContext.tsx @@ -3,11 +3,15 @@ import '../../../../../lib/monaco-setup'; import { Editor, type Monaco } from '@monaco-editor/react'; import type { editor } from 'monaco-editor'; -import { memo, useCallback, useEffect, useState } from 'react'; +import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { PrCommentAnchor, StoredPullRequest } from '@meebox/shared'; +import { EDITOR_FONT_SIZE_MIN } from '@meebox/shared'; import { invoke } from '../../../../../api'; import { editorFontSize } from '../../../../../lib/editor-font'; +import { useMonacoEditorTheme } from '../../../../../hooks/useTheme'; +import { useEditorAppearance } from '../../../../../stores/editor-appearance-store'; +import { resolveEditorFontFamily } from '../../../../../theme'; import { languageFor } from '../../../../../utils/language'; interface InlineCodeContextProps { @@ -111,8 +115,8 @@ function InlineCodeContextImpl({ return ; } -/** Monaco fs=12 时近似行高;上下各 6px padding */ -const SNIPPET_LINE_HEIGHT = 19; +/** 行内片段行高 / 字号比(源自 fs=12 时行高 19);按配置字号等比缩放行高。 */ +const SNIPPET_LINE_HEIGHT_RATIO = 19 / 12; const READONLY_OPTIONS: editor.IStandaloneEditorConstructionOptions = { readOnly: true, @@ -141,8 +145,25 @@ const CodeSnippet = memo(function CodeSnippet({ snippet: Snippet; language: string; }) { + // Monaco 内置主题不走 CSS 自定义属性,须显式切换:按编辑器主题偏好('auto' 跟随 GUI 深浅)解析。 + const monacoTheme = useMonacoEditorTheme(); + // 等宽字体 + 字号随配置切换。行内片段比主编辑器小 2px(保留历史观感)、随配置字号联动,下限受 MIN 约束; + // 行高按字号等比缩放。字号 / 行高 / 字体一并进 options(@monaco-editor/react 按引用比对,useMemo 稳定)。 + const appearance = useEditorAppearance(); + const fontFamily = resolveEditorFontFamily(appearance.fontFamily); + const snippetFontSize = Math.max(EDITOR_FONT_SIZE_MIN, appearance.fontSize - 2); + const lineHeight = Math.round(snippetFontSize * SNIPPET_LINE_HEIGHT_RATIO); + const options = useMemo( + () => ({ + ...READONLY_OPTIONS, + fontFamily, + fontSize: editorFontSize(snippetFontSize), + lineHeight, + }), + [fontFamily, snippetFontSize, lineHeight], + ); const lineCount = snippet.text.split('\n').length; - const height = lineCount * SNIPPET_LINE_HEIGHT + 12; + const height = lineCount * lineHeight + 12; const handleMount = useCallback( (ed: editor.IStandaloneCodeEditor, monaco: Monaco): void => { @@ -161,8 +182,7 @@ const CodeSnippet = memo(function CodeSnippet({ contextmenu: false, folding: false, glyphMargin: false, - fontSize: editorFontSize(12), - lineHeight: SNIPPET_LINE_HEIGHT, + // 字号 / 行高 / 字体由 options 统一驱动(随配置实时更新),不在此固定。 padding: { top: 6, bottom: 6 }, // 行宽自适应,长行用 word wrap 而不是横向滚动条 (滚动条已禁) wordWrap: 'on', @@ -188,9 +208,9 @@ const CodeSnippet = memo(function CodeSnippet({ height={`${String(height)}px`} language={language} value={snippet.text} - theme="vs-dark" + theme={monacoTheme} onMount={handleMount} - options={READONLY_OPTIONS} + options={options} /> ); diff --git a/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffPane.tsx b/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffPane.tsx index cf775f71..bd456b5e 100644 --- a/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffPane.tsx +++ b/apps/desktop/src/renderer/src/components/features/pr/tabs/diff/DiffPane.tsx @@ -4,6 +4,9 @@ import { DiffEditor } from '@monaco-editor/react'; import { type editor as MonacoEditor } from 'monaco-editor'; import type { DiffChangedFile } from '@meebox/ipc'; import { editorFontSize } from '../../../../../lib/editor-font'; +import { useMonacoEditorTheme } from '../../../../../hooks/useTheme'; +import { useEditorAppearance } from '../../../../../stores/editor-appearance-store'; +import { resolveEditorFontFamily } from '../../../../../theme'; import { languageFor } from '../../../../../utils/language'; import { PaneLoading } from '../../../../common'; import { Spinner } from './DiffStatus'; @@ -27,6 +30,11 @@ export function DiffPane({ onMount: (editor: MonacoEditor.IStandaloneDiffEditor) => void; }) { const { t } = useTranslation(); + // Monaco 内置主题不走 CSS 自定义属性,须显式切换:按编辑器主题偏好('auto' 跟随 GUI 深浅)解析。 + const monacoTheme = useMonacoEditorTheme(); + // 编辑器等宽字体 + 字号:随配置切换(字体空 = Monaco 默认;字号按平台再做微调)。 + const editorAppearance = useEditorAppearance(); + const fontFamily = resolveEditorFontFamily(editorAppearance.fontFamily); // Monaco 挂载后 diff 还要异步计算 + hideUnchangedRegions 折叠才稳定(见上文 reveal 逻辑), // 期间编辑器是「空 → 跳一下」的重排。在它之上盖一层 overlay loading,首次 onDidUpdateDiff // (或挂载即已算完)后卸载,遮住这段抖动一次性 reveal。DiffPane 按 file path keyed → @@ -36,7 +44,7 @@ export function DiffPane({ // editor.updateOptions()。父级 DiffView 随 poll(pr 换新对象引用)重渲染 → DiffPane 重渲染, // 若每次新建 options 字面量,每次 poll 都触发 updateOptions → hideUnchangedRegions 折叠布局重算 → // 编辑器渲染抖动。只在真正影响项(并排/空白/字号)变化时重建。 - const fontSize = editorFontSize(14); + const fontSize = editorFontSize(editorAppearance.fontSize); const editorOptions = useMemo( () => ({ readOnly: true, @@ -46,6 +54,7 @@ export function DiffPane({ automaticLayout: true, minimap: { enabled: false }, fontSize, + fontFamily, scrollBeyondLastLine: false, // 关掉 diff 专属的合并总览列(renderOverviewRuler=true 会在两侧滚动条之外再加一条宽列, // 跟 VS Code 编辑模式「滚动条内打标」不一致)。改走编辑模式效果:内层 modified 编辑器自带的 @@ -75,7 +84,7 @@ export function DiffPane({ stickyScroll: { enabled: false }, occurrencesHighlight: 'off', }), - [renderSideBySide, showWhitespace, fontSize], + [renderSideBySide, showWhitespace, fontSize, fontFamily], ); const handleMount = useCallback( (editor: MonacoEditor.IStandaloneDiffEditor) => { @@ -127,7 +136,7 @@ export function DiffPane({ .join(' ') || undefined } options={editorOptions} - theme="vs-dark" + theme={monacoTheme} /> ); diff --git a/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx b/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx index 27db360a..f1673b48 100644 --- a/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx +++ b/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx @@ -1,6 +1,13 @@ import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import type { AppInfo, AppPaths, Config, SupportedLanguage } from '@meebox/shared'; +import type { + AppInfo, + AppPaths, + Config, + EditorTheme, + SupportedLanguage, + ThemePreference, +} from '@meebox/shared'; import { ConfirmModal, GlobeIcon, @@ -14,6 +21,8 @@ import { ConnectionEditorModal } from './editors/ConnectionEditorModal'; import { LlmEditorModal } from './editors/LlmEditorModal'; import { ProxyEditorModal } from './editors/ProxyEditorModal'; import { LanguageSection } from './sections/LanguageSection'; +import { ThemeSection } from './sections/ThemeSection'; +import { EditorSection } from './sections/EditorSection'; import { ConnectionsSection } from './sections/ConnectionsSection'; import { PollerSection } from './sections/PollerSection'; import { LlmSection } from './sections/LlmSection'; @@ -49,6 +58,14 @@ interface SettingsModalProps { onProxyChange?: (proxy: Config['proxy']) => void; /** UI 语言即时切换后通知父级同步 boot.config.language(与写盘/实时切换解耦的状态同步) */ onLanguageChange?: (language: SupportedLanguage) => void; + /** GUI 主题即时切换后通知父级同步 boot.config.appearance.theme(同语言,解耦状态同步) */ + onThemeChange?: (theme: ThemePreference) => void; + /** 编辑器外观(Monaco 主题 + 等宽字体 + 字号)即时改动后通知父级同步 boot.config.appearance */ + onEditorAppearanceChange?: (appearance: { + editor_theme: EditorTheme; + editor_font_family: string; + editor_font_size: number; + }) => void; /** * 连接改动(含切换活动连接)保存成功后通知父级。父级需重拉 config + 连接摘要 + PR 列表: * 活动连接变化后,main 端 app:connections 只返回新活动连接的摘要、prs:list 只返回其 PR, @@ -69,6 +86,8 @@ export function SettingsModal({ onLlmChange, onProxyChange, onLanguageChange, + onThemeChange, + onEditorAppearanceChange, onConnectionsChange, onClose, }: SettingsModalProps) { @@ -80,6 +99,8 @@ export function SettingsModal({ onLlmChange, onProxyChange, onLanguageChange, + onThemeChange, + onEditorAppearanceChange, onConnectionsChange, onClose, }); @@ -131,14 +152,26 @@ export function SettingsModal({ aria-current={category === id ? 'page' : undefined} onClick={() => setCategory(id)} > - + {t(labelKey)} ))}
{category === 'general' && ( - + <> + + + + )} {category === 'connection' && ( <> diff --git a/apps/desktop/src/renderer/src/components/features/settings/hooks/useSettingsDraft.ts b/apps/desktop/src/renderer/src/components/features/settings/hooks/useSettingsDraft.ts index 847380a6..13cdf512 100644 --- a/apps/desktop/src/renderer/src/components/features/settings/hooks/useSettingsDraft.ts +++ b/apps/desktop/src/renderer/src/components/features/settings/hooks/useSettingsDraft.ts @@ -1,8 +1,18 @@ import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import type { AppPaths, Config, LlmProfile, SupportedLanguage } from '@meebox/shared'; +import type { + AppPaths, + Config, + EditorTheme, + LlmProfile, + SupportedLanguage, + ThemePreference, +} from '@meebox/shared'; +import { EDITOR_FONT_SIZE_MAX, EDITOR_FONT_SIZE_MIN } from '@meebox/shared'; import { invoke } from '../../../../api'; import i18n, { persistLanguage, resolveUiLanguage } from '../../../../i18n'; +import { applyEditorFontFamily, applyThemePreference, persistThemePreference } from '../../../../theme'; +import { setEditorAppearance } from '../../../../stores/editor-appearance-store'; import { fromConnDraft, toConnDraft, type ConnDraft } from '../ConnectionForm'; import { newProfileId } from '../LlmProfileForm'; @@ -12,6 +22,12 @@ interface UseSettingsDraftParams { onLlmChange?: (llm: Config['llm']) => void; onProxyChange?: (proxy: Config['proxy']) => void; onLanguageChange?: (language: SupportedLanguage) => void; + onThemeChange?: (theme: ThemePreference) => void; + onEditorAppearanceChange?: (appearance: { + editor_theme: EditorTheme; + editor_font_family: string; + editor_font_size: number; + }) => void; onConnectionsChange?: () => void | Promise; onClose: () => void; } @@ -27,6 +43,8 @@ export function useSettingsDraft({ onLlmChange, onProxyChange, onLanguageChange, + onThemeChange, + onEditorAppearanceChange, onConnectionsChange, onClose, }: UseSettingsDraftParams) { @@ -87,6 +105,68 @@ export function useSettingsDraft({ }); }; + // GUI 主题:与语言同属即时生效项(不走全局保存)。改即写 data-theme + 持久化 + 同步父级 + 写盘。 + const [themePreference, setThemePreference] = useState(config.appearance.theme); + const handleThemeChange = (next: ThemePreference): void => { + if (next === themePreference) return; + setThemePreference(next); + applyThemePreference(next); // 渲染层实时切换(写 documentElement data-theme) + persistThemePreference(next); // localStorage 缓存,下次启动同步命中 + onThemeChange?.(next); // 同步父级 boot.config.appearance.theme + invoke('config:setTheme', { theme: next }).catch((e: unknown) => { + // 写盘失败不回滚 UI(已切),仅提示;下次启动按 localStorage 兜底 + setSaveError(e instanceof Error ? e.message : String(e)); + }); + }; + + // 编辑器外观(Monaco 主题 + 等宽字体):即时生效项。主题为离散选择 → 改即写盘;字体为文本输入 → + // onChange 仅实时预览(写 store + CSS + 同步父级),onBlur 才写盘,避免逐字符落盘。 + const [editorTheme, setEditorTheme] = useState(config.appearance.editor_theme); + const [editorFontFamily, setEditorFontFamily] = useState( + config.appearance.editor_font_family, + ); + const [editorFontSize, setEditorFontSizeState] = useState( + config.appearance.editor_font_size, + ); + // 实时应用到运行时:写共享 store(Monaco 组件读)+ 字体 CSS 变量(全应用 $font-mono)+ 同步父级。 + const applyEditorAppearance = (nextTheme: EditorTheme, nextFont: string, nextSize: number): void => { + setEditorAppearance({ editorTheme: nextTheme, fontFamily: nextFont, fontSize: nextSize }); + applyEditorFontFamily(nextFont); + onEditorAppearanceChange?.({ + editor_theme: nextTheme, + editor_font_family: nextFont, + editor_font_size: nextSize, + }); + }; + const persistEditorAppearance = (nextTheme: EditorTheme, nextFont: string, nextSize: number): void => { + invoke('config:setEditorAppearance', { + editor_theme: nextTheme, + editor_font_family: nextFont, + editor_font_size: nextSize, + }).catch((e: unknown) => setSaveError(e instanceof Error ? e.message : String(e))); + }; + const handleEditorThemeChange = (next: EditorTheme): void => { + if (next === editorTheme) return; + setEditorTheme(next); + applyEditorAppearance(next, editorFontFamily, editorFontSize); + persistEditorAppearance(next, editorFontFamily, editorFontSize); + }; + const handleEditorFontChange = (next: string): void => { + setEditorFontFamily(next); + applyEditorAppearance(editorTheme, next, editorFontSize); // 实时预览,不写盘 + }; + const commitEditorFont = (): void => { + persistEditorAppearance(editorTheme, editorFontFamily, editorFontSize); // 失焦才写盘 + }; + // 字号为离散下拉 → 改即生效并写盘;clamp 防越界(异常 / config 手改超范围)。 + const handleEditorFontSizeChange = (next: number): void => { + const clamped = Math.min(EDITOR_FONT_SIZE_MAX, Math.max(EDITOR_FONT_SIZE_MIN, Math.round(next))); + if (clamped === editorFontSize) return; + setEditorFontSizeState(clamped); + applyEditorAppearance(editorTheme, editorFontFamily, clamped); + persistEditorAppearance(editorTheme, editorFontFamily, clamped); + }; + const [totalBytes, setTotalBytes] = useState(null); useEffect(() => { invoke('repo:getTotalSize', undefined) @@ -320,6 +400,17 @@ export function useSettingsDraft({ // 语言 language, handleLanguageChange, + // 主题 + themePreference, + handleThemeChange, + // 编辑器外观 + editorTheme, + editorFontFamily, + editorFontSize, + handleEditorThemeChange, + handleEditorFontChange, + commitEditorFont, + handleEditorFontSizeChange, // 连接 connections, activeConnId, diff --git a/apps/desktop/src/renderer/src/components/features/settings/sections/AgentDirSection.tsx b/apps/desktop/src/renderer/src/components/features/settings/sections/AgentDirSection.tsx index 982c13e1..1ad708ad 100644 --- a/apps/desktop/src/renderer/src/components/features/settings/sections/AgentDirSection.tsx +++ b/apps/desktop/src/renderer/src/components/features/settings/sections/AgentDirSection.tsx @@ -13,7 +13,7 @@ export function AgentDirSection({ }) { const { t } = useTranslation(); return ( -
+
{/* 标题行:左侧标题 + 右侧蓝色「打开当前目录」按钮(在系统文件管理器打开生效的 Agent 目录, 便于直接查看 / 编辑文件)。放在标题行而非配置行,避免与下方的目录选择按钮混淆。 */}
diff --git a/apps/desktop/src/renderer/src/components/features/settings/sections/CacheDirSection.tsx b/apps/desktop/src/renderer/src/components/features/settings/sections/CacheDirSection.tsx index 0e4eff4d..4951cb3a 100644 --- a/apps/desktop/src/renderer/src/components/features/settings/sections/CacheDirSection.tsx +++ b/apps/desktop/src/renderer/src/components/features/settings/sections/CacheDirSection.tsx @@ -18,7 +18,7 @@ export function CacheDirSection({ }) { const { t } = useTranslation(); return ( -
+

{t('settings.cacheDirTitle')}

{t('settings.cacheDirHint')} diff --git a/apps/desktop/src/renderer/src/components/features/settings/sections/EditorSection.tsx b/apps/desktop/src/renderer/src/components/features/settings/sections/EditorSection.tsx new file mode 100644 index 00000000..47cb22f8 --- /dev/null +++ b/apps/desktop/src/renderer/src/components/features/settings/sections/EditorSection.tsx @@ -0,0 +1,91 @@ +import { useTranslation } from 'react-i18next'; +import { EDITOR_FONT_SIZE_PRESETS, EDITOR_THEME_OPTIONS, type EditorTheme } from '@meebox/shared'; + +/** + * 编辑器外观分区:代码编辑器(Monaco)配色主题选择 + 等宽字体 + 字号配置。三项均即时生效(字体输入失焦才 + * 写盘,onChange 实时预览),由 useSettingsDraft 编排。本分区在「常规」内以分隔线与语言 / 主题分组。 + * + * 字体仿 VS Code `editor.fontFamily`:自由输入、可逗号分隔多个候选(按序优先),整体作为 font-family + * 前缀拼到内置 mono 字体栈之前(拼接见 theme/resolveEditorFontFamily)。不做本机字体枚举(枚举会阻塞 UI + * 1~2s)。主题里 'auto'(跟随应用)走 i18n、其余主题用专名。 + */ +export function EditorSection({ + theme, + fontFamily, + fontSize, + onThemeChange, + onFontChange, + onFontCommit, + onFontSizeChange, +}: { + theme: EditorTheme; + fontFamily: string; + fontSize: number; + onThemeChange: (next: EditorTheme) => void; + onFontChange: (next: string) => void; + onFontCommit: () => void; + onFontSizeChange: (next: number) => void; +}) { + const { t } = useTranslation(); + // 当前字号若不在预设档位(config 手改),并入下拉、按数值排序,保证选中态可见。 + const sizeOptions = [...new Set([...EDITOR_FONT_SIZE_PRESETS, fontSize])].sort( + (a, b) => a - b, + ); + + return ( +

+
+

{t('settings.editorThemeTitle')}

+ +
+

+ {t('settings.editorThemeHint')} +

+ {/* 字体为自由输入(可能较长的逗号分隔列表)→ 单独成行、输入框铺满,不与标题挤在一行。 */} +
+

{t('settings.editorFontTitle')}

+ onFontChange(e.target.value)} + onBlur={onFontCommit} + aria-label={t('settings.editorFontTitle')} + /> +
+

+ {t('settings.editorFontHint')} +

+
+

{t('settings.editorFontSizeTitle')}

+ +
+

+ {t('settings.editorFontSizeHint')} +

+
+ ); +} diff --git a/apps/desktop/src/renderer/src/components/features/settings/sections/ThemeSection.tsx b/apps/desktop/src/renderer/src/components/features/settings/sections/ThemeSection.tsx new file mode 100644 index 00000000..7b3bcbfd --- /dev/null +++ b/apps/desktop/src/renderer/src/components/features/settings/sections/ThemeSection.tsx @@ -0,0 +1,41 @@ +import { useTranslation } from 'react-i18next'; +import { THEME_PREFERENCES, type ThemePreference } from '@meebox/shared'; + +/** 主题偏好选项 → i18n key(选项文案随 UI 语言翻译,区别于语言项的 endonym)。 */ +const THEME_OPTION_KEYS: Record = { + system: 'settings.themeOptionSystem', + light: 'settings.themeOptionLight', + dark: 'settings.themeOptionDark', +}; + +export function ThemeSection({ + theme, + onChange, +}: { + theme: ThemePreference; + onChange: (next: ThemePreference) => void; +}) { + const { t } = useTranslation(); + return ( +
+
+

{t('settings.themeTitle')}

+ +
+

+ {t('settings.themeHint')} +

+
+ ); +} diff --git a/apps/desktop/src/renderer/src/hooks/useTheme.ts b/apps/desktop/src/renderer/src/hooks/useTheme.ts new file mode 100644 index 00000000..23e31bfe --- /dev/null +++ b/apps/desktop/src/renderer/src/hooks/useTheme.ts @@ -0,0 +1,65 @@ +import { useEffect, useSyncExternalStore } from 'react'; +import type { Config, ResolvedTheme, ThemePreference } from '@meebox/shared'; +import { applyEditorFontFamily, applyThemePreference, persistThemePreference, watchSystemTheme } from '../theme'; +import { setEditorAppearance, useEditorAppearance } from '../stores/editor-appearance-store'; + +/** + * 跟随主题偏好生效:偏好变化时把它解析后写到 documentElement.data-theme + 持久化到 localStorage + * (供下次启动同步命中);'system' 偏好下还监听 OS 深 / 浅色切换、实时重解析跟随。 + * + * 偏好源为 config.appearance.theme(启动 boot.config 注入,设置页即时改动经 patchConfig 同步), + * 故主题切换与语言切换走同一条「config 驱动 + 即时生效」路径。 + */ +export function useTheme(preference: ThemePreference): void { + useEffect(() => { + applyThemePreference(preference); + persistThemePreference(preference); + return watchSystemTheme(preference); + }, [preference]); +} + +/** 订阅 documentElement.data-theme 变化(含 system 偏好下 OS 切换)。 */ +function subscribeResolvedTheme(onChange: () => void): () => void { + const obs = new MutationObserver(onChange); + obs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); + return () => obs.disconnect(); +} + +function getResolvedThemeSnapshot(): ResolvedTheme { + return document.documentElement.dataset.theme === 'light' ? 'light' : 'dark'; +} + +/** + * 当前实际生效的视觉主题(解析后的 light / dark),随 data-theme 变化实时更新。供需按主题切换内部 + * 配色的非 CSS 组件用(如 Monaco 编辑器、Mermaid —— 它们的主题不走 CSS 自定义属性,须显式传入)。 + */ +export function useResolvedTheme(): ResolvedTheme { + return useSyncExternalStore(subscribeResolvedTheme, getResolvedThemeSnapshot); +} + +/** + * 把 config.appearance 的编辑器外观同步到运行时:写入共享 store(供 Monaco 组件读)+ 应用等宽字体 + * CSS 变量(供全应用 $font-mono)。源为 config(启动注入、设置页即时改动经 patchConfig 同步)。 + */ +export function useEditorAppearanceSync(appearance: Config['appearance']): void { + const { editor_theme, editor_font_family, editor_font_size } = appearance; + useEffect(() => { + setEditorAppearance({ + editorTheme: editor_theme, + fontFamily: editor_font_family, + fontSize: editor_font_size, + }); + applyEditorFontFamily(editor_font_family); + }, [editor_theme, editor_font_family, editor_font_size]); +} + +/** + * 当前生效的 Monaco 编辑器主题名:编辑器主题偏好为 'auto' 时跟随 GUI 解析主题(浅 'vs' / 深 'vs-dark'), + * 否则用所选 Monaco 内置主题(vs / vs-dark / hc-black / hc-light)。 + */ +export function useMonacoEditorTheme(): string { + const { editorTheme } = useEditorAppearance(); + const resolved = useResolvedTheme(); + if (editorTheme === 'auto') return resolved === 'light' ? 'vs' : 'vs-dark'; + return editorTheme; +} diff --git a/apps/desktop/src/renderer/src/i18n/locales/de-DE.json b/apps/desktop/src/renderer/src/i18n/locales/de-DE.json index e391e77d..10b76ec9 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/de-DE.json +++ b/apps/desktop/src/renderer/src/i18n/locales/de-DE.json @@ -675,6 +675,14 @@ "editConfigYaml": "config.yaml bearbeiten", "editConnectionTitle": "Verbindung bearbeiten", "editLlmTitle": "LLM-Modell bearbeiten", + "editorFontHint": "Schriftfamilie für den Editor und Monospace-Text; mehrere Schriften kommagetrennt (in Reihenfolge), vor dem eingebauten Monospace-Stack eingefügt. Leer lassen, um den eingebauten Stack zu verwenden.", + "editorFontPlaceholder": "z. B. JetBrains Mono, Fira Code", + "editorFontSizeHint": "Schriftgröße des Code-Editors in Pixeln.", + "editorFontSizeTitle": "Editor-Schriftgröße", + "editorFontTitle": "Editor-Schriftart", + "editorThemeHint": "Farbschema des Code-Editors. „Automatisch“ entspricht dem hellen/dunklen Design der App.", + "editorThemeOptionAuto": "Automatisch", + "editorThemeTitle": "Editor-Design", "enableConnectionAria": "Diese Verbindung aktivieren", "enableProxy": "Proxy aktivieren", "experimental": "Experimentell", @@ -730,6 +738,11 @@ "testFailed": "Fehlgeschlagen", "testProxy": "Verbindung testen", "testing": "Teste…", + "themeHint": "Wird sofort angewendet. „System“ folgt der Hell-/Dunkel-Einstellung des Betriebssystems.", + "themeOptionDark": "Dunkel", + "themeOptionLight": "Hell", + "themeOptionSystem": "System", + "themeTitle": "Design", "title": "Einstellungen", "upToDate": "Aktuell", "updateAvailableLabel": "↑ Neue Version v{{version}} · Zum Download", diff --git a/apps/desktop/src/renderer/src/i18n/locales/en-US.json b/apps/desktop/src/renderer/src/i18n/locales/en-US.json index 9048d12d..05bcc94b 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/en-US.json +++ b/apps/desktop/src/renderer/src/i18n/locales/en-US.json @@ -675,6 +675,14 @@ "editConfigYaml": "Edit config.yaml", "editConnectionTitle": "Edit Connection", "editLlmTitle": "Edit LLM Model", + "editorFontHint": "Font family for the editor and monospaced text; comma-separate multiple fonts (used in order), placed ahead of the built-in monospace stack. Leave empty to use the built-in stack.", + "editorFontPlaceholder": "e.g. JetBrains Mono, Fira Code", + "editorFontSizeHint": "Font size for the code editor, in pixels.", + "editorFontSizeTitle": "Editor Font Size", + "editorFontTitle": "Editor Font", + "editorThemeHint": "Color theme for the code editor. “Auto” matches the app’s light/dark theme.", + "editorThemeOptionAuto": "Auto", + "editorThemeTitle": "Editor Theme", "enableConnectionAria": "Activate this connection", "enableProxy": "Enable Proxy", "experimental": "Experimental", @@ -730,6 +738,11 @@ "testFailed": "Failed", "testProxy": "Test Connection", "testing": "Testing…", + "themeHint": "Applies immediately. “System” follows your operating system’s light/dark setting.", + "themeOptionDark": "Dark", + "themeOptionLight": "Light", + "themeOptionSystem": "System", + "themeTitle": "Theme", "title": "Settings", "upToDate": "Up to date", "updateAvailableLabel": "↑ New version v{{version}} · Go to download", diff --git a/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json b/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json index ca572ced..a418ebd2 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json +++ b/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json @@ -659,6 +659,14 @@ "editConfigYaml": "config.yaml を編集", "editConnectionTitle": "接続を編集", "editLlmTitle": "LLM モデルを編集", + "editorFontHint": "エディターと等幅テキストのフォントファミリー。カンマ区切りで複数指定でき(順に優先)、内蔵の等幅フォントスタックの前に挿入されます。空欄の場合は内蔵スタックを使用します。", + "editorFontPlaceholder": "例: JetBrains Mono, Fira Code", + "editorFontSizeHint": "コードエディターのフォントサイズ(ピクセル)。", + "editorFontSizeTitle": "エディターのフォントサイズ", + "editorFontTitle": "エディターのフォント", + "editorThemeHint": "コードエディターの配色テーマ。「自動」はアプリのライト / ダークテーマに追従します。", + "editorThemeOptionAuto": "自動", + "editorThemeTitle": "エディターのテーマ", "enableConnectionAria": "この接続を有効化", "enableProxy": "プロキシを有効化", "experimental": "実験的", @@ -714,6 +722,11 @@ "testFailed": "失敗", "testProxy": "接続テスト", "testing": "テスト中…", + "themeHint": "選択するとすぐに切り替わります。「システムに従う」は OS のライト / ダーク設定に追従します。", + "themeOptionDark": "ダーク", + "themeOptionLight": "ライト", + "themeOptionSystem": "システムに従う", + "themeTitle": "テーマ", "title": "設定", "upToDate": "最新です", "updateAvailableLabel": "↑ 新しいバージョン v{{version}} · ダウンロードへ", diff --git a/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json b/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json index f83e6b0a..2b5a5e10 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json +++ b/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json @@ -659,6 +659,14 @@ "editConfigYaml": "编辑 config.yaml", "editConnectionTitle": "编辑连接", "editLlmTitle": "编辑 LLM 模型", + "editorFontHint": "编辑器与等宽文本使用的字体族;可逗号分隔多个候选(按顺序优先),整体置于内置等宽字体栈之前。留空则用内置字体栈。", + "editorFontPlaceholder": "如 JetBrains Mono, Fira Code", + "editorFontSizeHint": "代码编辑器的字号(像素)。", + "editorFontSizeTitle": "编辑器字号", + "editorFontTitle": "编辑器字体", + "editorThemeHint": "代码编辑器的配色主题。「自动」与应用的浅色 / 深色主题保持一致。", + "editorThemeOptionAuto": "自动", + "editorThemeTitle": "编辑器主题", "enableConnectionAria": "启用该连接", "enableProxy": "启用代理", "experimental": "实验性", @@ -714,6 +722,11 @@ "testFailed": "失败", "testProxy": "测试连通", "testing": "测试中…", + "themeHint": "选择后立即切换;「跟随系统」随操作系统的浅色 / 深色设置变化。", + "themeOptionDark": "深色", + "themeOptionLight": "浅色", + "themeOptionSystem": "跟随系统", + "themeTitle": "主题", "title": "设置", "upToDate": "已是最新版", "updateAvailableLabel": "↑ 新版本 v{{version}} · 前往下载", diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/NOTICE.md b/apps/desktop/src/renderer/src/lib/editor-themes/NOTICE.md new file mode 100644 index 00000000..ac48daff --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/NOTICE.md @@ -0,0 +1,18 @@ +# 编辑器主题(vendored) + +本目录的 `*.json` 为代码编辑器(Monaco)可选配色主题,均为 `monaco.editor.IStandaloneThemeData` +形状,经 monaco-setup 的 `defineTheme` 注册;按 `EDITOR_THEME_OPTIONS`(`@meebox/shared`)的 id +命名(kebab-case)。来源两类,均为 MIT License: + +- 社区主题(GitHub / Monokai / Dracula / Nord / Solarized 等)取自 + [brijeshb42/monaco-themes](https://github.com/brijeshb42/monaco-themes)。 +- `dark-2026.json` / `light-2026.json` 由 VS Code 内置默认主题 + [microsoft/vscode](https://github.com/microsoft/vscode)(`extensions/theme-defaults/themes/2026-*.json`) + 转换而来:已解析其 `include` 链(→ dark_modern → …)合并,并把 `tokenColors` / `colors` 转为 Monaco 形状。 + +就地内置(vendored)而非作为 npm 依赖引入:monaco-themes 的 `exports` 未暴露 `./themes/*` 子路径, +打包器无法解析其内部 JSON;VS Code 主题同理无独立分发包。原始主题部分源自社区 TextMate 主题,版权归 +各自作者;此处仅作再分发,保留上述出处与许可声明。 + +注:Monaco 用 Monarch 着色(非 TextMate 语法),故主题对细粒度 scope 的着色保真度低于 VS Code; +编辑器底色 / 前景 / 常见 token(注释 / 字符串 / 关键字 / 数字等)一致。 diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/cobalt2.json b/apps/desktop/src/renderer/src/lib/editor-themes/cobalt2.json new file mode 100644 index 00000000..2c6c37b3 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/cobalt2.json @@ -0,0 +1,859 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "193549", + "token": "" + }, + { + "foreground": "e1efff", + "token": "punctuation - (punctuation.definition.string || punctuation.definition.comment)" + }, + { + "foreground": "ff628c", + "token": "constant" + }, + { + "foreground": "ffc600", + "token": "entity" + }, + { + "foreground": "ff9d00", + "token": "keyword" + }, + { + "foreground": "ffc600", + "token": "storage" + }, + { + "foreground": "3ad900", + "token": "string -string.unquoted.old-plist -string.unquoted.heredoc" + }, + { + "foreground": "3ad900", + "token": "string.unquoted.heredoc string" + }, + { + "foreground": "0088ff", + "fontStyle": "italic", + "token": "comment" + }, + { + "foreground": "80ffbb", + "token": "support" + }, + { + "foreground": "cccccc", + "background": "0d3a58", + "token": "variable" + }, + { + "foreground": "ff80e1", + "token": "variable.language" + }, + { + "foreground": "ffee80", + "token": "meta.function-call" + }, + { + "foreground": "f8f8f8", + "background": "800f00", + "token": "invalid" + }, + { + "foreground": "80fcff", + "fontStyle": "italic", + "token": "entity.other.inherited-class" + }, + { + "foreground": "9eff80", + "token": "string.quoted source" + }, + { + "foreground": "9eff80", + "token": "string.quoted" + }, + { + "foreground": "80ff82", + "token": "string constant" + }, + { + "foreground": "80ffc2", + "token": "string.regexp" + }, + { + "foreground": "edef7d", + "token": "string variable" + }, + { + "foreground": "ffb054", + "token": "support.function" + }, + { + "foreground": "eb939a", + "token": "support.constant" + }, + { + "foreground": "ff1e00", + "token": "support.type.exception" + }, + { + "foreground": "8996a8", + "token": "meta.preprocessor.c" + }, + { + "foreground": "afc4db", + "token": "meta.preprocessor.c keyword" + }, + { + "foreground": "73817d", + "token": "meta.sgml.html meta.doctype" + }, + { + "foreground": "73817d", + "token": "meta.sgml.html meta.doctype entity" + }, + { + "foreground": "73817d", + "token": "meta.sgml.html meta.doctype string" + }, + { + "foreground": "73817d", + "token": "meta.xml-processing" + }, + { + "foreground": "73817d", + "token": "meta.xml-processing entity" + }, + { + "foreground": "73817d", + "token": "meta.xml-processing string" + }, + { + "foreground": "9effff", + "token": "meta.tag" + }, + { + "foreground": "9effff", + "token": "meta.tag entity" + }, + { + "foreground": "9effff", + "token": "meta.selector.css entity.name.tag" + }, + { + "foreground": "ffb454", + "token": "meta.selector.css entity.other.attribute-name.id" + }, + { + "foreground": "5fe461", + "token": "meta.selector.css entity.other.attribute-name.class" + }, + { + "foreground": "9df39f", + "token": "support.type.property-name.css" + }, + { + "foreground": "f6f080", + "token": "meta.property-group support.constant.property-value.css" + }, + { + "foreground": "f6f080", + "token": "meta.property-value support.constant.property-value.css" + }, + { + "foreground": "f6aa11", + "token": "meta.preprocessor.at-rule keyword.control.at-rule" + }, + { + "foreground": "edf080", + "token": "meta.property-value support.constant.named-color.css" + }, + { + "foreground": "edf080", + "token": "meta.property-value constant" + }, + { + "foreground": "eb939a", + "token": "meta.constructor.argument.css" + }, + { + "foreground": "f8f8f8", + "background": "000e1a", + "token": "meta.diff" + }, + { + "foreground": "f8f8f8", + "background": "000e1a", + "token": "meta.diff.header" + }, + { + "foreground": "f8f8f8", + "background": "ee3a43", + "token": "markup.deleted" + }, + { + "foreground": "f8f8f8", + "background": "806f00", + "token": "markup.changed" + }, + { + "foreground": "f8f8f8", + "background": "154f00", + "token": "markup.inserted" + }, + { + "background": "8fddf630", + "token": "markup.raw" + }, + { + "background": "004480", + "token": "markup.quote" + }, + { + "background": "1d425d", + "token": "markup.list" + }, + { + "foreground": "c1afff", + "fontStyle": "bold", + "token": "markup.bold" + }, + { + "foreground": "b8ffd9", + "fontStyle": "italic", + "token": "markup.italic" + }, + { + "foreground": "c8e4fd", + "background": "001221", + "fontStyle": "bold", + "token": "markup.heading" + }, + { + "foreground": "ffffff", + "background": "ffffaa", + "token": "sublimelinter.annotations" + }, + { + "foreground": "da2000", + "token": "sublimelinter.mark.error" + }, + { + "foreground": "ffffff", + "background": "ff4a52", + "token": "sublimelinter.outline.illegal" + }, + { + "background": "ff0000", + "token": "sublimelinter.underline.illegal" + }, + { + "foreground": "ffffff", + "token": "sublimelinter.gutter-mark" + }, + { + "foreground": "edba00", + "token": "sublimelinter.mark.warning" + }, + { + "foreground": "ffffff", + "background": "df9400", + "token": "sublimelinter.outline.warning" + }, + { + "background": "ff0000", + "token": "sublimelinter.underline.warning" + }, + { + "foreground": "ffffff", + "background": "ffffff", + "token": "sublimelinter.outline.violation" + }, + { + "background": "ff0000", + "token": "sublimelinter.underline.violation" + }, + { + "foreground": "80ffc2", + "token": "" + }, + { + "foreground": "80ffc2", + "token": "entity.name.class.php" + }, + { + "foreground": "80ffc2", + "token": "" + }, + { + "foreground": "80ffc2", + "token": "entity.name.type.class.php" + }, + { + "foreground": "80ffc2", + "token": "" + }, + { + "background": "333333", + "token": "entity.name.function.php" + }, + { + "foreground": "f92672", + "token": "markup.deleted.git_gutter" + }, + { + "foreground": "a6e22e", + "token": "markup.inserted.git_gutter" + }, + { + "foreground": "967efb", + "token": "markup.changed.git_gutter" + }, + { + "foreground": "565656", + "token": "markup.ignored.git_gutter" + }, + { + "foreground": "565656", + "token": "markup.untracked.git_gutter" + }, + { + "foreground": "1f4662", + "token": "brackethighlighter.tag" + }, + { + "foreground": "ffc600", + "token": "brackethighlighter.curly" + }, + { + "foreground": "ffc600", + "token": "brackethighlighter.round" + }, + { + "foreground": "ffc600", + "token": "brackethighlighter.square" + }, + { + "foreground": "ffdd00", + "token": "brackethighlighter.angle" + }, + { + "foreground": "ffc600", + "token": "brackethighlighter.quote" + }, + { + "foreground": "f92672", + "token": "brackethighlighter.unmatched" + }, + { + "foreground": "ffa5f3", + "background": "1d3c52", + "token": "storage.type.function.js" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.begin.js" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.end.js" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "2affdf", + "token": "string.unquoted.label.js" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "2affdf", + "token": "meta.object-literal.key.js" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "80ffbb", + "token": "meta.object-literal.key.string.quoted" + }, + { + "foreground": "ffc600", + "token": "meta.object-literal.key.entity" + }, + { + "foreground": "ffffff", + "token": "meta.object-literal.key.punctuation" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.template.begin.js" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.template.end.js" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "9eff80", + "token": "string.template.js" + }, + { + "foreground": "ffffff", + "token": "" + }, + { + "foreground": "ffffff", + "token": "string.template.js punctuation" + }, + { + "foreground": "ffffff", + "token": "" + }, + { + "foreground": "ffc600", + "token": "template.entity" + }, + { + "foreground": "ff80e1", + "token": "string.template variable" + }, + { + "foreground": "ffa5f3", + "background": "1d3c52", + "token": "storage.type.function.jsx" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.begin.jsx" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.end.jsx" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "2affdf", + "token": "string.unquoted.label.jsx" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "2affdf", + "token": "meta.object-literal.key.jsx" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "80ffbb", + "token": "meta.object-literal.key.string.quoted" + }, + { + "foreground": "ffc600", + "token": "meta.object-literal.key.entity" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.template.begin.jsx" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.template.end.jsx" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "9eff80", + "token": "string.template.jsx" + }, + { + "foreground": "ffffff", + "token": "" + }, + { + "foreground": "ffffff", + "token": "string.template.jsx punctuation" + }, + { + "foreground": "ffffff", + "token": "" + }, + { + "foreground": "ffa5f3", + "background": "1d3c52", + "token": "storage.type.function.ts" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.begin.ts" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.end.ts" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.template.begin.ts" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "2eff00", + "token": "punctuation.definition.string.template.end.ts" + }, + { + "foreground": "2eff00", + "token": "" + }, + { + "foreground": "9eff80", + "token": "string.template.ts" + }, + { + "foreground": "ffffff", + "token": "" + }, + { + "foreground": "ffffff", + "token": "string.template.ts punctuation" + }, + { + "foreground": "ffffff", + "token": "" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "2affdf", + "token": "string.unquoted.label.ts" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "2affdf", + "token": "meta.object-literal.key.ts" + }, + { + "foreground": "2affdf", + "token": "" + }, + { + "foreground": "fb94ff", + "token": "" + }, + { + "foreground": "fb94ff", + "token": "entity.name.class.js" + }, + { + "foreground": "fb94ff", + "token": "" + }, + { + "foreground": "fb94ff", + "token": "entity.name.type.class.js" + }, + { + "foreground": "fb94ff", + "token": "" + }, + { + "foreground": "fb94ff", + "token": "entity.name.class.jsx" + }, + { + "foreground": "fb94ff", + "token": "" + }, + { + "foreground": "fb94ff", + "token": "entity.name.type.class.jsx" + }, + { + "foreground": "fb94ff", + "token": "" + }, + { + "foreground": "ff9d00", + "token": "" + }, + { + "foreground": "ff9d00", + "token": "storage.type.class.js" + }, + { + "foreground": "ff9d00", + "token": "" + }, + { + "foreground": "ff9d00", + "token": "storage.type.class.jsx" + }, + { + "foreground": "ff9d00", + "token": "" + }, + { + "fontStyle": "italic", + "token": "" + }, + { + "fontStyle": "italic", + "token": "storage.type.extends.js" + }, + { + "fontStyle": "italic", + "token": "" + }, + { + "fontStyle": "italic", + "token": "storage.modifier.extends.js" + }, + { + "fontStyle": "italic", + "token": "" + }, + { + "fontStyle": "italic", + "token": "storage.type.extends.jsx" + }, + { + "fontStyle": "italic", + "token": "" + }, + { + "fontStyle": "italic", + "token": "storage.modifier.extends.jsx" + }, + { + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "token": "punctuation.separator.key-value.css" + }, + { + "foreground": "0088ff", + "background": "17344a", + "token": "invalid.illegal.bad-comments-or-CDATA.html" + }, + { + "foreground": "ffc600", + "token": "" + }, + { + "foreground": "ffc600", + "token": "punctuation.definition.list_item.markdown" + }, + { + "foreground": "ffc600", + "token": "" + }, + { + "foreground": "ffc600", + "token": "punctuation.definition.blockquote.markdown" + }, + { + "foreground": "ffc600", + "token": "" + }, + { + "foreground": "ffc600", + "token": "punctuation.definition.string.begin.markdown" + }, + { + "foreground": "ffc600", + "token": "" + }, + { + "foreground": "ffc600", + "token": "punctuation.definition.string.end.markdown" + }, + { + "foreground": "ffc600", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "markup.underline.link.image.markdown" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.html" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.event.html" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.class.html" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.style.html" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.id.html" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.tag.jade" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "constant.other.symbol.ruby" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "entity.other.attribute-name.jsx" + }, + { + "foreground": "ffc600", + "fontStyle": "italic", + "token": "" + } + ], + "colors": { + "editor.foreground": "#FFFFFF", + "editor.background": "#193549", + "editor.selectionBackground": "#0050a4", + "editor.lineHighlightBackground": "#1f4662", + "editorCursor.foreground": "#ffc600", + "editorWhitespace.foreground": "#7f7f7fb2", + "editorIndentGuide.background": "#3b5364", + "editorIndentGuide.activeBackground": "#ffc600" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/dark-2026.json b/apps/desktop/src/renderer/src/lib/editor-themes/dark-2026.json new file mode 100644 index 00000000..fa911462 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/dark-2026.json @@ -0,0 +1,1399 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "token": "meta.embedded", + "foreground": "D4D4D4" + }, + { + "token": "source.groovy.embedded", + "foreground": "D4D4D4" + }, + { + "token": "string meta.image.inline.markdown", + "foreground": "D4D4D4" + }, + { + "token": "variable.legacy.builtin.python", + "foreground": "D4D4D4" + }, + { + "token": "emphasis", + "fontStyle": "italic" + }, + { + "token": "strong", + "fontStyle": "bold" + }, + { + "token": "header", + "foreground": "000080" + }, + { + "token": "comment", + "foreground": "6A9955" + }, + { + "token": "constant.language", + "foreground": "569cd6" + }, + { + "token": "constant.numeric", + "foreground": "b5cea8" + }, + { + "token": "variable.other.enummember", + "foreground": "b5cea8" + }, + { + "token": "keyword.operator.plus.exponent", + "foreground": "b5cea8" + }, + { + "token": "keyword.operator.minus.exponent", + "foreground": "b5cea8" + }, + { + "token": "constant.regexp", + "foreground": "646695" + }, + { + "token": "entity.name.tag", + "foreground": "569cd6" + }, + { + "token": "entity.name.tag.css", + "foreground": "d7ba7d" + }, + { + "token": "entity.name.tag.less", + "foreground": "d7ba7d" + }, + { + "token": "entity.other.attribute-name", + "foreground": "9cdcfe" + }, + { + "token": "entity.other.attribute-name.class.css", + "foreground": "d7ba7d" + }, + { + "token": "source.css entity.other.attribute-name.class", + "foreground": "d7ba7d" + }, + { + "token": "entity.other.attribute-name.id.css", + "foreground": "d7ba7d" + }, + { + "token": "entity.other.attribute-name.parent-selector.css", + "foreground": "d7ba7d" + }, + { + "token": "entity.other.attribute-name.parent.less", + "foreground": "d7ba7d" + }, + { + "token": "source.css entity.other.attribute-name.pseudo-class", + "foreground": "d7ba7d" + }, + { + "token": "entity.other.attribute-name.pseudo-element.css", + "foreground": "d7ba7d" + }, + { + "token": "source.css.less entity.other.attribute-name.id", + "foreground": "d7ba7d" + }, + { + "token": "entity.other.attribute-name.scss", + "foreground": "d7ba7d" + }, + { + "token": "invalid", + "foreground": "f44747" + }, + { + "token": "markup.underline", + "fontStyle": "underline" + }, + { + "token": "markup.bold", + "foreground": "569cd6", + "fontStyle": "bold" + }, + { + "token": "markup.heading", + "foreground": "569cd6", + "fontStyle": "bold" + }, + { + "token": "markup.italic", + "foreground": "C586C0", + "fontStyle": "italic" + }, + { + "token": "markup.strikethrough", + "fontStyle": "strikethrough" + }, + { + "token": "markup.inserted", + "foreground": "b5cea8" + }, + { + "token": "markup.deleted", + "foreground": "ce9178" + }, + { + "token": "markup.changed", + "foreground": "569cd6" + }, + { + "token": "punctuation.definition.quote.begin.markdown", + "foreground": "6A9955" + }, + { + "token": "punctuation.definition.list.begin.markdown", + "foreground": "6796e6" + }, + { + "token": "markup.inline.raw", + "foreground": "ce9178" + }, + { + "token": "punctuation.definition.tag", + "foreground": "808080" + }, + { + "token": "meta.preprocessor", + "foreground": "569cd6" + }, + { + "token": "entity.name.function.preprocessor", + "foreground": "569cd6" + }, + { + "token": "meta.preprocessor.string", + "foreground": "ce9178" + }, + { + "token": "meta.preprocessor.numeric", + "foreground": "b5cea8" + }, + { + "token": "meta.structure.dictionary.key.python", + "foreground": "9cdcfe" + }, + { + "token": "meta.diff.header", + "foreground": "569cd6" + }, + { + "token": "storage", + "foreground": "569cd6" + }, + { + "token": "storage.type", + "foreground": "569cd6" + }, + { + "token": "storage.modifier", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.noexcept", + "foreground": "569cd6" + }, + { + "token": "string", + "foreground": "ce9178" + }, + { + "token": "meta.embedded.assembly", + "foreground": "ce9178" + }, + { + "token": "string.tag", + "foreground": "ce9178" + }, + { + "token": "string.value", + "foreground": "ce9178" + }, + { + "token": "string.regexp", + "foreground": "d16969" + }, + { + "token": "punctuation.definition.template-expression.begin", + "foreground": "569cd6" + }, + { + "token": "punctuation.definition.template-expression.end", + "foreground": "569cd6" + }, + { + "token": "punctuation.section.embedded", + "foreground": "569cd6" + }, + { + "token": "meta.template.expression", + "foreground": "d4d4d4" + }, + { + "token": "support.type.vendored.property-name", + "foreground": "9cdcfe" + }, + { + "token": "support.type.property-name", + "foreground": "9cdcfe" + }, + { + "token": "source.css variable", + "foreground": "9cdcfe" + }, + { + "token": "source.coffee.embedded", + "foreground": "9cdcfe" + }, + { + "token": "keyword", + "foreground": "569cd6" + }, + { + "token": "keyword.control", + "foreground": "569cd6" + }, + { + "token": "keyword.operator", + "foreground": "d4d4d4" + }, + { + "token": "keyword.operator.new", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.expression", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.cast", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.sizeof", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.alignof", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.typeid", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.alignas", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.instanceof", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.logical.python", + "foreground": "569cd6" + }, + { + "token": "keyword.operator.wordlike", + "foreground": "569cd6" + }, + { + "token": "keyword.other.unit", + "foreground": "b5cea8" + }, + { + "token": "punctuation.section.embedded.begin.php", + "foreground": "569cd6" + }, + { + "token": "punctuation.section.embedded.end.php", + "foreground": "569cd6" + }, + { + "token": "support.function.git-rebase", + "foreground": "9cdcfe" + }, + { + "token": "constant.sha.git-rebase", + "foreground": "b5cea8" + }, + { + "token": "storage.modifier.import.java", + "foreground": "d4d4d4" + }, + { + "token": "variable.language.wildcard.java", + "foreground": "d4d4d4" + }, + { + "token": "storage.modifier.package.java", + "foreground": "d4d4d4" + }, + { + "token": "variable.language", + "foreground": "569cd6" + }, + { + "token": "entity.name.function", + "foreground": "DCDCAA" + }, + { + "token": "support.function", + "foreground": "DCDCAA" + }, + { + "token": "support.constant.handlebars", + "foreground": "DCDCAA" + }, + { + "token": "source.powershell variable.other.member", + "foreground": "DCDCAA" + }, + { + "token": "entity.name.operator.custom-literal", + "foreground": "DCDCAA" + }, + { + "token": "support.class", + "foreground": "4EC9B0" + }, + { + "token": "support.type", + "foreground": "4EC9B0" + }, + { + "token": "entity.name.type", + "foreground": "4EC9B0" + }, + { + "token": "entity.name.namespace", + "foreground": "4EC9B0" + }, + { + "token": "entity.other.attribute", + "foreground": "4EC9B0" + }, + { + "token": "entity.name.scope-resolution", + "foreground": "4EC9B0" + }, + { + "token": "entity.name.class", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.numeric.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.byte.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.boolean.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.string.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.uintptr.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.error.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.rune.go", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.cs", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.generic.cs", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.modifier.cs", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.variable.cs", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.annotation.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.generic.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.object.array.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.primitive.array.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.primitive.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.token.java", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.groovy", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.annotation.groovy", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.parameters.groovy", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.generic.groovy", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.object.array.groovy", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.primitive.array.groovy", + "foreground": "4EC9B0" + }, + { + "token": "storage.type.primitive.groovy", + "foreground": "4EC9B0" + }, + { + "token": "meta.type.cast.expr", + "foreground": "4EC9B0" + }, + { + "token": "meta.type.new.expr", + "foreground": "4EC9B0" + }, + { + "token": "support.constant.math", + "foreground": "4EC9B0" + }, + { + "token": "support.constant.dom", + "foreground": "4EC9B0" + }, + { + "token": "support.constant.json", + "foreground": "4EC9B0" + }, + { + "token": "entity.other.inherited-class", + "foreground": "4EC9B0" + }, + { + "token": "punctuation.separator.namespace.ruby", + "foreground": "4EC9B0" + }, + { + "token": "keyword.control", + "foreground": "C586C0" + }, + { + "token": "source.cpp keyword.operator.new", + "foreground": "C586C0" + }, + { + "token": "keyword.operator.delete", + "foreground": "C586C0" + }, + { + "token": "keyword.other.using", + "foreground": "C586C0" + }, + { + "token": "keyword.other.directive.using", + "foreground": "C586C0" + }, + { + "token": "keyword.other.operator", + "foreground": "C586C0" + }, + { + "token": "entity.name.operator", + "foreground": "C586C0" + }, + { + "token": "variable", + "foreground": "9CDCFE" + }, + { + "token": "meta.definition.variable.name", + "foreground": "9CDCFE" + }, + { + "token": "support.variable", + "foreground": "9CDCFE" + }, + { + "token": "entity.name.variable", + "foreground": "9CDCFE" + }, + { + "token": "constant.other.placeholder", + "foreground": "9CDCFE" + }, + { + "token": "variable.other.constant", + "foreground": "4FC1FF" + }, + { + "token": "variable.other.enummember", + "foreground": "4FC1FF" + }, + { + "token": "meta.object-literal.key", + "foreground": "9CDCFE" + }, + { + "token": "support.constant.property-value", + "foreground": "CE9178" + }, + { + "token": "support.constant.font-name", + "foreground": "CE9178" + }, + { + "token": "support.constant.media-type", + "foreground": "CE9178" + }, + { + "token": "support.constant.media", + "foreground": "CE9178" + }, + { + "token": "constant.other.color.rgb-value", + "foreground": "CE9178" + }, + { + "token": "constant.other.rgb-value", + "foreground": "CE9178" + }, + { + "token": "support.constant.color", + "foreground": "CE9178" + }, + { + "token": "punctuation.definition.group.regexp", + "foreground": "CE9178" + }, + { + "token": "punctuation.definition.group.assertion.regexp", + "foreground": "CE9178" + }, + { + "token": "punctuation.definition.character-class.regexp", + "foreground": "CE9178" + }, + { + "token": "punctuation.character.set.begin.regexp", + "foreground": "CE9178" + }, + { + "token": "punctuation.character.set.end.regexp", + "foreground": "CE9178" + }, + { + "token": "keyword.operator.negation.regexp", + "foreground": "CE9178" + }, + { + "token": "support.other.parenthesis.regexp", + "foreground": "CE9178" + }, + { + "token": "constant.character.character-class.regexp", + "foreground": "d16969" + }, + { + "token": "constant.other.character-class.set.regexp", + "foreground": "d16969" + }, + { + "token": "constant.other.character-class.regexp", + "foreground": "d16969" + }, + { + "token": "constant.character.set.regexp", + "foreground": "d16969" + }, + { + "token": "keyword.operator.or.regexp", + "foreground": "DCDCAA" + }, + { + "token": "keyword.control.anchor.regexp", + "foreground": "DCDCAA" + }, + { + "token": "keyword.operator.quantifier.regexp", + "foreground": "d7ba7d" + }, + { + "token": "constant.character", + "foreground": "569cd6" + }, + { + "token": "constant.other.option", + "foreground": "569cd6" + }, + { + "token": "constant.character.escape", + "foreground": "d7ba7d" + }, + { + "token": "entity.name.label", + "foreground": "C8C8C8" + }, + { + "token": "comment", + "foreground": "8b949e" + }, + { + "token": "punctuation.definition.comment", + "foreground": "8b949e" + }, + { + "token": "string.comment", + "foreground": "8b949e" + }, + { + "token": "constant.other.placeholder", + "foreground": "ff7b72" + }, + { + "token": "constant.character", + "foreground": "ff7b72" + }, + { + "token": "constant", + "foreground": "79c0ff" + }, + { + "token": "entity.name.constant", + "foreground": "79c0ff" + }, + { + "token": "variable.other.constant", + "foreground": "79c0ff" + }, + { + "token": "variable.other.enummember", + "foreground": "79c0ff" + }, + { + "token": "variable.language", + "foreground": "79c0ff" + }, + { + "token": "entity", + "foreground": "79c0ff" + }, + { + "token": "entity.name", + "foreground": "ffa657" + }, + { + "token": "meta.export.default", + "foreground": "ffa657" + }, + { + "token": "meta.definition.variable", + "foreground": "ffa657" + }, + { + "token": "variable.parameter.function", + "foreground": "c9d1d9" + }, + { + "token": "meta.jsx.children", + "foreground": "c9d1d9" + }, + { + "token": "meta.block", + "foreground": "c9d1d9" + }, + { + "token": "meta.tag.attributes", + "foreground": "c9d1d9" + }, + { + "token": "entity.name.constant", + "foreground": "c9d1d9" + }, + { + "token": "meta.object.member", + "foreground": "c9d1d9" + }, + { + "token": "meta.embedded.expression", + "foreground": "c9d1d9" + }, + { + "token": "entity.name.function", + "foreground": "d2a8ff" + }, + { + "token": "entity.name.tag", + "foreground": "7ee787" + }, + { + "token": "support.class.component", + "foreground": "7ee787" + }, + { + "token": "keyword", + "foreground": "ff7b72" + }, + { + "token": "storage", + "foreground": "ff7b72" + }, + { + "token": "storage.type", + "foreground": "ff7b72" + }, + { + "token": "storage.modifier.package", + "foreground": "c9d1d9" + }, + { + "token": "storage.modifier.import", + "foreground": "c9d1d9" + }, + { + "token": "storage.type.java", + "foreground": "c9d1d9" + }, + { + "token": "string", + "foreground": "a5d6ff" + }, + { + "token": "string punctuation.section.embedded source", + "foreground": "a5d6ff" + }, + { + "token": "support", + "foreground": "79c0ff" + }, + { + "token": "meta.property-name", + "foreground": "79c0ff" + }, + { + "token": "variable", + "foreground": "ffa657" + }, + { + "token": "variable.other", + "foreground": "c9d1d9" + }, + { + "token": "invalid.broken", + "foreground": "ffa198", + "fontStyle": "italic" + }, + { + "token": "invalid.deprecated", + "foreground": "ffa198", + "fontStyle": "italic" + }, + { + "token": "invalid.illegal", + "foreground": "ffa198", + "fontStyle": "italic" + }, + { + "token": "invalid.unimplemented", + "foreground": "ffa198", + "fontStyle": "italic" + }, + { + "token": "carriage-return", + "foreground": "f0f6fc", + "background": "8b1111", + "fontStyle": "italic underline" + }, + { + "token": "message.error", + "foreground": "ffa198" + }, + { + "token": "string variable", + "foreground": "79c0ff" + }, + { + "token": "source.regexp", + "foreground": "a5d6ff" + }, + { + "token": "string.regexp", + "foreground": "a5d6ff" + }, + { + "token": "string.regexp.character-class", + "foreground": "a5d6ff" + }, + { + "token": "string.regexp constant.character.escape", + "foreground": "a5d6ff" + }, + { + "token": "string.regexp source.ruby.embedded", + "foreground": "a5d6ff" + }, + { + "token": "string.regexp string.regexp.arbitrary-repitition", + "foreground": "a5d6ff" + }, + { + "token": "string.regexp constant.character.escape", + "foreground": "7ee787", + "fontStyle": "bold" + }, + { + "token": "support.constant", + "foreground": "79c0ff" + }, + { + "token": "support.variable", + "foreground": "79c0ff" + }, + { + "token": "support.type.property-name.json", + "foreground": "7ee787" + }, + { + "token": "meta.module-reference", + "foreground": "79c0ff" + }, + { + "token": "punctuation.definition.list.begin.markdown", + "foreground": "ffa657" + }, + { + "token": "markup.heading", + "foreground": "79c0ff", + "fontStyle": "bold" + }, + { + "token": "markup.heading entity.name", + "foreground": "79c0ff", + "fontStyle": "bold" + }, + { + "token": "markup.quote", + "foreground": "7ee787" + }, + { + "token": "markup.italic", + "foreground": "c9d1d9", + "fontStyle": "italic" + }, + { + "token": "markup.bold", + "foreground": "c9d1d9", + "fontStyle": "bold" + }, + { + "token": "markup.underline", + "fontStyle": "underline" + }, + { + "token": "markup.strikethrough", + "fontStyle": "strikethrough" + }, + { + "token": "markup.inline.raw", + "foreground": "79c0ff" + }, + { + "token": "markup.deleted", + "foreground": "ffa198", + "background": "490202" + }, + { + "token": "meta.diff.header.from-file", + "foreground": "ffa198", + "background": "490202" + }, + { + "token": "punctuation.definition.deleted", + "foreground": "ffa198", + "background": "490202" + }, + { + "token": "punctuation.section.embedded", + "foreground": "ff7b72" + }, + { + "token": "markup.inserted", + "foreground": "7ee787", + "background": "04260f" + }, + { + "token": "meta.diff.header.to-file", + "foreground": "7ee787", + "background": "04260f" + }, + { + "token": "punctuation.definition.inserted", + "foreground": "7ee787", + "background": "04260f" + }, + { + "token": "markup.changed", + "foreground": "ffa657", + "background": "5a1e02" + }, + { + "token": "punctuation.definition.changed", + "foreground": "ffa657", + "background": "5a1e02" + }, + { + "token": "markup.ignored", + "foreground": "0d1117", + "background": "79c0ff" + }, + { + "token": "markup.untracked", + "foreground": "0d1117", + "background": "79c0ff" + }, + { + "token": "meta.diff.range", + "foreground": "d2a8ff", + "fontStyle": "bold" + }, + { + "token": "meta.diff.header", + "foreground": "79c0ff" + }, + { + "token": "meta.separator", + "foreground": "79c0ff", + "fontStyle": "bold" + }, + { + "token": "meta.output", + "foreground": "79c0ff" + }, + { + "token": "brackethighlighter.tag", + "foreground": "8b949e" + }, + { + "token": "brackethighlighter.curly", + "foreground": "8b949e" + }, + { + "token": "brackethighlighter.round", + "foreground": "8b949e" + }, + { + "token": "brackethighlighter.square", + "foreground": "8b949e" + }, + { + "token": "brackethighlighter.angle", + "foreground": "8b949e" + }, + { + "token": "brackethighlighter.quote", + "foreground": "8b949e" + }, + { + "token": "brackethighlighter.unmatched", + "foreground": "ffa198" + }, + { + "token": "constant.other.reference.link", + "foreground": "a5d6ff" + }, + { + "token": "string.other.link", + "foreground": "a5d6ff" + }, + { + "token": "token.info-token", + "foreground": "6796E6" + }, + { + "token": "token.warn-token", + "foreground": "CD9731" + }, + { + "token": "token.error-token", + "foreground": "F44747" + }, + { + "token": "token.debug-token", + "foreground": "B267E6" + } + ], + "colors": { + "checkbox.border": "#707070", + "editor.background": "#121314", + "editor.foreground": "#BBBEBF", + "editor.inactiveSelectionBackground": "#27678260", + "editorIndentGuide.background1": "#404040", + "editorIndentGuide.activeBackground1": "#707070", + "editor.selectionHighlightBackground": "#27678260", + "list.dropBackground": "#3994BC1A", + "activityBarBadge.background": "#3994BC", + "sideBarTitle.foreground": "#bfbfbf", + "input.placeholderForeground": "#555555", + "menu.background": "#202122", + "menu.foreground": "#bfbfbf", + "menu.separatorBackground": "#2A2B2C", + "menu.border": "#2A2B2CFF", + "menu.selectionBackground": "#3994BC26", + "statusBarItem.remoteForeground": "#FFFFFF", + "statusBarItem.remoteBackground": "#0078D4", + "ports.iconRunningProcessForeground": "#369432", + "sideBarSectionHeader.background": "#191A1B", + "sideBarSectionHeader.border": "#2A2B2CFF", + "tab.selectedBackground": "#222222", + "tab.selectedForeground": "#ffffffa0", + "tab.lastPinnedBorder": "#2A2B2CFF", + "list.activeSelectionIconForeground": "#FFF", + "terminal.inactiveSelectionBackground": "#3A3D41", + "widget.border": "#2A2B2CFF", + "actionBar.toggledBackground": "#383a49", + "agentsPanel.border": "#2A2B2CFF", + "agentsChatInput.border": "#333536", + "agentsChatInput.focusBorder": "#3994BCB3", + "agentsNewSessionButton.border": "#333536", + "activityBar.activeBorder": "#bfbfbf", + "activityBar.background": "#191A1B", + "activityBar.border": "#2A2B2CFF", + "activityBar.foreground": "#bfbfbf", + "activityBar.inactiveForeground": "#8C8C8C", + "activityBarBadge.foreground": "#FFFFFF", + "badge.background": "#3994BCF0", + "badge.foreground": "#FFFFFF", + "button.background": "#297AA0", + "button.border": "#297AA0", + "button.foreground": "#FFFFFF", + "button.hoverBackground": "#2B7DA3", + "button.secondaryBackground": "#00000000", + "button.secondaryForeground": "#CCCCCC", + "button.secondaryHoverBackground": "#FFFFFF10", + "chat.slashCommandBackground": "#26477866", + "chat.slashCommandForeground": "#85B6FF", + "chat.editedFileForeground": "#E2C08D", + "checkbox.background": "#242526", + "debugToolBar.background": "#181818", + "descriptionForeground": "#8C8C8C", + "dropdown.background": "#191A1B", + "dropdown.border": "#333536", + "dropdown.foreground": "#bfbfbf", + "dropdown.listBackground": "#191A1B", + "editor.findMatchBackground": "#27678290", + "editorGroup.border": "#FFFFFF17", + "editorGroupHeader.tabsBackground": "#191A1B", + "editorGroupHeader.tabsBorder": "#2A2B2CFF", + "editorGutter.addedBackground": "#72C892", + "editorGutter.deletedBackground": "#F28772", + "editorGutter.modifiedBackground": "#0078D4", + "editorLineNumber.activeForeground": "#BBBEBF", + "editorLineNumber.foreground": "#858889", + "editorOverviewRuler.border": "#2A2B2CFF", + "editorWidget.background": "#202122", + "errorForeground": "#f48771", + "focusBorder": "#3994BCB3", + "foreground": "#bfbfbf", + "icon.foreground": "#8C8C8C", + "input.background": "#191A1B", + "input.border": "#333536FF", + "input.foreground": "#bfbfbf", + "inputOption.activeBackground": "#3994BC33", + "inputOption.activeBorder": "#2A2B2CFF", + "keybindingLabel.foreground": "#CCCCCC", + "notificationCenterHeader.background": "#242526", + "notificationCenterHeader.foreground": "#bfbfbf", + "notifications.background": "#202122", + "notifications.border": "#2A2B2CFF", + "notifications.foreground": "#bfbfbf", + "panel.background": "#191A1B", + "panel.border": "#2A2B2CFF", + "panelInput.border": "#2B2B2B", + "panelTitle.activeBorder": "#3994BC", + "panelTitle.activeForeground": "#bfbfbf", + "panelTitle.inactiveForeground": "#8C8C8C", + "peekViewEditor.background": "#191A1B", + "peekViewEditor.matchHighlightBackground": "#3994BC33", + "peekViewResult.background": "#191A1B", + "peekViewResult.matchHighlightBackground": "#3994BC33", + "pickerGroup.border": "#2A2B2CFF", + "progressBar.background": "#878889", + "quickInput.background": "#202122", + "quickInput.foreground": "#bfbfbf", + "settings.dropdownBackground": "#313131", + "settings.dropdownBorder": "#3C3C3C", + "settings.headerForeground": "#FFFFFF", + "settings.modifiedItemIndicator": "#BB800966", + "sideBar.background": "#191A1B", + "sideBar.border": "#2A2B2CFF", + "sideBar.foreground": "#bfbfbf", + "sideBarSectionHeader.foreground": "#bfbfbf", + "statusBar.background": "#191A1B", + "statusBar.border": "#2A2B2CFF", + "statusBarItem.hoverBackground": "#323233", + "statusBarItem.hoverForeground": "#FFFFFF", + "statusBar.debuggingBackground": "#3994BC", + "statusBar.debuggingForeground": "#FFFFFF", + "statusBar.focusBorder": "#3994BCB3", + "statusBar.foreground": "#8C8C8C", + "statusBar.noFolderBackground": "#191A1B", + "statusBarItem.focusBorder": "#3994BCB3", + "statusBarItem.prominentBackground": "#3994BC", + "tab.activeBackground": "#121314", + "tab.activeBorder": "#121314", + "tab.activeBorderTop": "#3994BC", + "tab.activeForeground": "#bfbfbf", + "tab.selectedBorderTop": "#6caddf", + "tab.border": "#2A2B2CFF", + "tab.hoverBackground": "#121314", + "tab.inactiveBackground": "#191A1B", + "tab.inactiveForeground": "#8C8C8C", + "tab.unfocusedActiveBorder": "#1F1F1F", + "tab.unfocusedActiveBorderTop": "#2B2B2B", + "tab.unfocusedHoverBackground": "#1F1F1F", + "terminal.foreground": "#CCCCCC", + "terminal.tab.activeBorder": "#3994BC00", + "textBlockQuote.background": "#242526", + "textBlockQuote.border": "#2A2B2CFF", + "textCodeBlock.background": "#242526", + "textLink.activeForeground": "#53A5CA", + "textLink.foreground": "#48A0C7", + "textPreformat.foreground": "#8C8C8C", + "textPreformat.background": "#262626", + "textSeparator.foreground": "#2a2a2aFF", + "titleBar.activeBackground": "#191A1B", + "titleBar.activeForeground": "#8C8C8C", + "titleBar.border": "#2A2B2CFF", + "titleBar.inactiveBackground": "#191A1B", + "titleBar.inactiveForeground": "#8C8C8C", + "welcomePage.tileBackground": "#2B2B2B", + "welcomePage.progress.foreground": "#0078D4", + "disabledForeground": "#555555", + "button.secondaryBorder": "#333536", + "checkbox.foreground": "#8C8C8C", + "inputOption.activeForeground": "#bfbfbf", + "inputValidation.infoBackground": "#1E3A47", + "inputValidation.infoBorder": "#3994BC", + "inputValidation.infoForeground": "#bfbfbf", + "inputValidation.warningBackground": "#352A05", + "inputValidation.warningBorder": "#B89500", + "inputValidation.warningForeground": "#bfbfbf", + "inputValidation.errorBackground": "#3A1D1D", + "inputValidation.errorBorder": "#BE1100", + "inputValidation.errorForeground": "#bfbfbf", + "scrollbar.shadow": "#191B1D4D", + "scrollbarSlider.background": "#A8A9AA85", + "scrollbarSlider.hoverBackground": "#A8A9AA90", + "scrollbarSlider.activeBackground": "#A8A9AA9C", + "list.activeSelectionBackground": "#3994BC26", + "list.activeSelectionForeground": "#ededed", + "list.inactiveSelectionBackground": "#2C2D2E", + "list.inactiveSelectionForeground": "#ededed", + "list.hoverBackground": "#1E1F20", + "list.hoverForeground": "#bfbfbf", + "toolbar.hoverBackground": "#323233", + "toolbar.activeBackground": "#3C3C3D", + "list.focusBackground": "#3994BC26", + "list.focusForeground": "#bfbfbf", + "list.focusOutline": "#3994BCB3", + "list.highlightForeground": "#48A0C7", + "list.invalidItemForeground": "#444444", + "list.errorForeground": "#f48771", + "list.warningForeground": "#e5ba7d", + "activityBar.activeFocusBorder": "#3994BCB3", + "activityBarTop.activeBorder": "#bfbfbf", + "menubar.selectionBackground": "#242526", + "menubar.selectionForeground": "#bfbfbf", + "menu.selectionForeground": "#bfbfbf", + "menu.selectionBorder": "#3994BC", + "commandCenter.foreground": "#bfbfbf", + "commandCenter.activeForeground": "#bfbfbf", + "commandCenter.background": "#191A1B", + "commandCenter.activeBackground": "#FFFFFF0F", + "commandCenter.border": "#2E3031", + "editorStickyScroll.background": "#121314", + "editorStickyScrollHover.background": "#202122", + "editorStickyScroll.border": "#2A2B2CFF", + "editorCursor.foreground": "#BBBEBF", + "editor.selectionBackground": "#276782dd", + "editor.wordHighlightBackground": "#27678250", + "editor.wordHighlightStrongBackground": "#27678280", + "editor.findMatchHighlightBackground": "#27678280", + "editor.findRangeHighlightBackground": "#242526", + "editor.hoverHighlightBackground": "#242526", + "editor.lineHighlightBackground": "#242526", + "editor.rangeHighlightBackground": "#242526", + "editorLink.activeForeground": "#3a94bc", + "editorWhitespace.foreground": "#8C8C8C4D", + "editorIndentGuide.background": "#8384854D", + "editorIndentGuide.activeBackground": "#838485", + "editorRuler.foreground": "#848484", + "editorCodeLens.foreground": "#8C8C8C", + "editorBracketMatch.background": "#3994BC55", + "editorBracketMatch.border": "#2A2B2CFF", + "editorWidget.border": "#2A2B2CFF", + "editorWidget.foreground": "#bfbfbf", + "editorSuggestWidget.background": "#202122", + "editorSuggestWidget.border": "#2A2B2CFF", + "editorSuggestWidget.foreground": "#bfbfbf", + "editorSuggestWidget.highlightForeground": "#bfbfbf", + "editorSuggestWidget.selectedBackground": "#3994BC26", + "editorHoverWidget.background": "#202122", + "editorHoverWidget.border": "#2A2B2CFF", + "peekView.border": "#2A2B2CFF", + "peekViewResult.fileForeground": "#bfbfbf", + "peekViewResult.lineForeground": "#8C8C8C", + "peekViewResult.selectionBackground": "#3994BC26", + "peekViewResult.selectionForeground": "#bfbfbf", + "peekViewTitle.background": "#242526", + "peekViewTitleDescription.foreground": "#8C8C8C", + "peekViewTitleLabel.foreground": "#bfbfbf", + "editorGutter.background": "#121314", + "diffEditor.insertedLineBackground": "#347d3926", + "diffEditor.insertedTextBackground": "#57ab5a4d", + "diffEditor.removedLineBackground": "#c93c3726", + "diffEditor.removedTextBackground": "#f470674d", + "editorOverviewRuler.findMatchForeground": "#3a94bc99", + "editorOverviewRuler.modifiedForeground": "#6ab890", + "editorOverviewRuler.addedForeground": "#73c991", + "editorOverviewRuler.deletedForeground": "#f48771", + "editorOverviewRuler.errorForeground": "#f48771", + "editorOverviewRuler.warningForeground": "#e5ba7d", + "statusBar.noFolderForeground": "#8C8C8C", + "statusBarItem.activeBackground": "#4B4C4D", + "statusBarItem.prominentForeground": "#FFFFFF", + "statusBarItem.prominentHoverBackground": "#3994BC", + "tab.hoverForeground": "#bfbfbf", + "tab.unfocusedActiveBackground": "#121314", + "tab.unfocusedActiveForeground": "#8C8C8C", + "tab.unfocusedInactiveBackground": "#191A1B", + "tab.unfocusedInactiveForeground": "#444444", + "breadcrumb.foreground": "#8C8C8C", + "breadcrumb.background": "#121314", + "breadcrumb.focusForeground": "#bfbfbf", + "breadcrumb.activeSelectionForeground": "#bfbfbf", + "breadcrumbPicker.background": "#202122", + "notificationCenter.border": "#2A2B2CFF", + "notificationToast.border": "#2A2B2CFF", + "notificationLink.foreground": "#3a94bc", + "notificationsWarningIcon.foreground": "#CCA700", + "notificationsErrorIcon.foreground": "#f48771", + "notificationsInfoIcon.foreground": "#3a94bc", + "activityWarningBadge.foreground": "#202020", + "activityWarningBadge.background": "#CCA700", + "activityErrorBadge.foreground": "#FFFFFF", + "activityErrorBadge.background": "#f48771", + "extensionButton.prominentBackground": "#297AA0", + "extensionButton.prominentForeground": "#FFFFFF", + "extensionButton.prominentHoverBackground": "#2B7DA3", + "pickerGroup.foreground": "#bfbfbf", + "quickInputList.focusBackground": "#297AA0", + "quickInputList.focusForeground": "#FFFFFF", + "quickInputList.focusIconForeground": "#FFFFFF", + "quickInputList.focusHighlightForeground": "#FFFFFF", + "quickInputList.hoverBackground": "#1E1F20", + "terminal.selectionBackground": "#3994BC33", + "terminal.background": "#191A1B", + "terminal.border": "#2A2B2CFF", + "terminalCursor.foreground": "#bfbfbf", + "terminalCursor.background": "#191A1B", + "gitDecoration.addedResourceForeground": "#73c991", + "gitDecoration.modifiedResourceForeground": "#e5ba7d", + "gitDecoration.deletedResourceForeground": "#f48771", + "gitDecoration.untrackedResourceForeground": "#73c991", + "gitDecoration.ignoredResourceForeground": "#8C8C8C", + "gitDecoration.conflictingResourceForeground": "#f48771", + "gitDecoration.stageModifiedResourceForeground": "#e5ba7d", + "gitDecoration.stageDeletedResourceForeground": "#f48771", + "quickInputTitle.background": "#202122", + "commandCenter.activeBorder": "#333536", + "quickInput.border": "#333536", + "gauge.foreground": "#59a4f9", + "gauge.background": "#58A4F94D", + "gauge.border": "#2A2C2EFF", + "gauge.warningForeground": "#e5ba7d", + "gauge.warningBackground": "#E3B97E4D", + "gauge.errorForeground": "#f48771", + "gauge.errorBackground": "#F287724D", + "chat.requestBubbleBackground": "#ffffff13", + "chat.requestBubbleHoverBackground": "#ffffff22", + "chat.inputWorkingBorderColor1": "#297AA0", + "chat.inputWorkingBorderColor2": "#1C546F", + "chat.inputWorkingBorderColor3": "#5BA8CC", + "editorCommentsWidget.rangeBackground": "#488FAE26", + "editorCommentsWidget.rangeActiveBackground": "#488FAE46", + "charts.foreground": "#CCCCCC", + "charts.lines": "#C8CACC80", + "charts.blue": "#57A3F8", + "charts.red": "#EF8773", + "charts.yellow": "#E0B97F", + "charts.orange": "#CD861A", + "charts.green": "#86CF86", + "charts.purple": "#AD80D7", + "inlineChat.border": "#00000000", + "minimapSlider.background": "#A8A9AA85", + "minimapSlider.hoverBackground": "#A8A9AA90", + "minimapSlider.activeBackground": "#A8A9AA9C", + "agents.background": "#121314", + "agentsPanel.background": "#191A1B", + "agentsPanel.foreground": "#bfbfbf", + "agentsGradient.tintColor": "#297AA0", + "agentsChatInput.background": "#202122", + "agentsChatInput.foreground": "#bfbfbf", + "agentsChatInput.placeholderForeground": "#555555", + "agentsNewSessionButton.background": "#00000000", + "agentsNewSessionButton.foreground": "#bfbfbf", + "agentsNewSessionButton.hoverBackground": "#FFFFFF18", + "agentsBadge.background": "#3994BC", + "agentsBadge.foreground": "#FFFFFF", + "agentsUnreadBadge.background": "#3994BC", + "agentsUnreadBadge.foreground": "#FFFFFF" + } +} diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/dracula.json b/apps/desktop/src/renderer/src/lib/editor-themes/dracula.json new file mode 100644 index 00000000..7a0fa558 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/dracula.json @@ -0,0 +1,208 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "282a36", + "token": "" + }, + { + "foreground": "6272a4", + "token": "comment" + }, + { + "foreground": "f1fa8c", + "token": "string" + }, + { + "foreground": "bd93f9", + "token": "constant.numeric" + }, + { + "foreground": "bd93f9", + "token": "constant.language" + }, + { + "foreground": "bd93f9", + "token": "constant.character" + }, + { + "foreground": "bd93f9", + "token": "constant.other" + }, + { + "foreground": "ffb86c", + "token": "variable.other.readwrite.instance" + }, + { + "foreground": "ff79c6", + "token": "constant.character.escaped" + }, + { + "foreground": "ff79c6", + "token": "constant.character.escape" + }, + { + "foreground": "ff79c6", + "token": "string source" + }, + { + "foreground": "ff79c6", + "token": "string source.ruby" + }, + { + "foreground": "ff79c6", + "token": "keyword" + }, + { + "foreground": "ff79c6", + "token": "storage" + }, + { + "foreground": "8be9fd", + "fontStyle": "italic", + "token": "storage.type" + }, + { + "foreground": "50fa7b", + "fontStyle": "underline", + "token": "entity.name.class" + }, + { + "foreground": "50fa7b", + "fontStyle": "italic underline", + "token": "entity.other.inherited-class" + }, + { + "foreground": "50fa7b", + "token": "entity.name.function" + }, + { + "foreground": "ffb86c", + "fontStyle": "italic", + "token": "variable.parameter" + }, + { + "foreground": "ff79c6", + "token": "entity.name.tag" + }, + { + "foreground": "50fa7b", + "token": "entity.other.attribute-name" + }, + { + "foreground": "8be9fd", + "token": "support.function" + }, + { + "foreground": "6be5fd", + "token": "support.constant" + }, + { + "foreground": "66d9ef", + "fontStyle": " italic", + "token": "support.type" + }, + { + "foreground": "66d9ef", + "fontStyle": " italic", + "token": "support.class" + }, + { + "foreground": "f8f8f0", + "background": "ff79c6", + "token": "invalid" + }, + { + "foreground": "f8f8f0", + "background": "bd93f9", + "token": "invalid.deprecated" + }, + { + "foreground": "cfcfc2", + "token": "meta.structure.dictionary.json string.quoted.double.json" + }, + { + "foreground": "6272a4", + "token": "meta.diff" + }, + { + "foreground": "6272a4", + "token": "meta.diff.header" + }, + { + "foreground": "ff79c6", + "token": "markup.deleted" + }, + { + "foreground": "50fa7b", + "token": "markup.inserted" + }, + { + "foreground": "e6db74", + "token": "markup.changed" + }, + { + "foreground": "bd93f9", + "token": "constant.numeric.line-number.find-in-files - match" + }, + { + "foreground": "e6db74", + "token": "entity.name.filename" + }, + { + "foreground": "f83333", + "token": "message.error" + }, + { + "foreground": "eeeeee", + "token": "punctuation.definition.string.begin.json - meta.structure.dictionary.value.json" + }, + { + "foreground": "eeeeee", + "token": "punctuation.definition.string.end.json - meta.structure.dictionary.value.json" + }, + { + "foreground": "8be9fd", + "token": "meta.structure.dictionary.json string.quoted.double.json" + }, + { + "foreground": "f1fa8c", + "token": "meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "50fa7b", + "token": "meta meta meta meta meta meta meta.structure.dictionary.value string" + }, + { + "foreground": "ffb86c", + "token": "meta meta meta meta meta meta.structure.dictionary.value string" + }, + { + "foreground": "ff79c6", + "token": "meta meta meta meta meta.structure.dictionary.value string" + }, + { + "foreground": "bd93f9", + "token": "meta meta meta meta.structure.dictionary.value string" + }, + { + "foreground": "50fa7b", + "token": "meta meta meta.structure.dictionary.value string" + }, + { + "foreground": "ffb86c", + "token": "meta meta.structure.dictionary.value string" + } + ], + "colors": { + "editor.foreground": "#f8f8f2", + "editor.background": "#282a36", + "editor.selectionBackground": "#44475a", + "editor.lineHighlightBackground": "#44475a", + "editorCursor.foreground": "#f8f8f0", + "editorWhitespace.foreground": "#3B3A32", + "editorIndentGuide.activeBackground": "#9D550FB0", + "editor.selectionHighlightBorder": "#222218" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/github-dark.json b/apps/desktop/src/renderer/src/lib/editor-themes/github-dark.json new file mode 100644 index 00000000..b6225a85 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/github-dark.json @@ -0,0 +1,348 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "24292e", + "token": "" + }, + { + "foreground": "959da5", + "token": "comment" + }, + { + "foreground": "959da5", + "token": "punctuation.definition.comment" + }, + { + "foreground": "959da5", + "token": "string.comment" + }, + { + "foreground": "c8e1ff", + "token": "constant" + }, + { + "foreground": "c8e1ff", + "token": "entity.name.constant" + }, + { + "foreground": "c8e1ff", + "token": "variable.other.constant" + }, + { + "foreground": "c8e1ff", + "token": "variable.language" + }, + { + "foreground": "b392f0", + "token": "entity" + }, + { + "foreground": "b392f0", + "token": "entity.name" + }, + { + "foreground": "f6f8fa", + "token": "variable.parameter.function" + }, + { + "foreground": "7bcc72", + "token": "entity.name.tag" + }, + { + "foreground": "ea4a5a", + "token": "keyword" + }, + { + "foreground": "ea4a5a", + "token": "storage" + }, + { + "foreground": "ea4a5a", + "token": "storage.type" + }, + { + "foreground": "f6f8fa", + "token": "storage.modifier.package" + }, + { + "foreground": "f6f8fa", + "token": "storage.modifier.import" + }, + { + "foreground": "f6f8fa", + "token": "storage.type.java" + }, + { + "foreground": "79b8ff", + "token": "string" + }, + { + "foreground": "79b8ff", + "token": "punctuation.definition.string" + }, + { + "foreground": "79b8ff", + "token": "string punctuation.section.embedded source" + }, + { + "foreground": "c8e1ff", + "token": "support" + }, + { + "foreground": "c8e1ff", + "token": "meta.property-name" + }, + { + "foreground": "fb8532", + "token": "variable" + }, + { + "foreground": "f6f8fa", + "token": "variable.other" + }, + { + "foreground": "d73a49", + "fontStyle": "bold italic underline", + "token": "invalid.broken" + }, + { + "foreground": "d73a49", + "fontStyle": "bold italic underline", + "token": "invalid.deprecated" + }, + { + "foreground": "fafbfc", + "background": "d73a49", + "fontStyle": "italic underline", + "token": "invalid.illegal" + }, + { + "foreground": "fafbfc", + "background": "d73a49", + "fontStyle": "italic underline", + "token": "carriage-return" + }, + { + "foreground": "d73a49", + "fontStyle": "bold italic underline", + "token": "invalid.unimplemented" + }, + { + "foreground": "d73a49", + "token": "message.error" + }, + { + "foreground": "f6f8fa", + "token": "string source" + }, + { + "foreground": "c8e1ff", + "token": "string variable" + }, + { + "foreground": "79b8ff", + "token": "source.regexp" + }, + { + "foreground": "79b8ff", + "token": "string.regexp" + }, + { + "foreground": "79b8ff", + "token": "string.regexp.character-class" + }, + { + "foreground": "79b8ff", + "token": "string.regexp constant.character.escape" + }, + { + "foreground": "79b8ff", + "token": "string.regexp source.ruby.embedded" + }, + { + "foreground": "79b8ff", + "token": "string.regexp string.regexp.arbitrary-repitition" + }, + { + "foreground": "7bcc72", + "fontStyle": "bold", + "token": "string.regexp constant.character.escape" + }, + { + "foreground": "c8e1ff", + "token": "support.constant" + }, + { + "foreground": "c8e1ff", + "token": "support.variable" + }, + { + "foreground": "c8e1ff", + "token": "meta.module-reference" + }, + { + "foreground": "fb8532", + "token": "markup.list" + }, + { + "foreground": "0366d6", + "fontStyle": "bold", + "token": "markup.heading" + }, + { + "foreground": "0366d6", + "fontStyle": "bold", + "token": "markup.heading entity.name" + }, + { + "foreground": "c8e1ff", + "token": "markup.quote" + }, + { + "foreground": "f6f8fa", + "fontStyle": "italic", + "token": "markup.italic" + }, + { + "foreground": "f6f8fa", + "fontStyle": "bold", + "token": "markup.bold" + }, + { + "foreground": "c8e1ff", + "token": "markup.raw" + }, + { + "foreground": "b31d28", + "background": "ffeef0", + "token": "markup.deleted" + }, + { + "foreground": "b31d28", + "background": "ffeef0", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "b31d28", + "background": "ffeef0", + "token": "punctuation.definition.deleted" + }, + { + "foreground": "176f2c", + "background": "f0fff4", + "token": "markup.inserted" + }, + { + "foreground": "176f2c", + "background": "f0fff4", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "176f2c", + "background": "f0fff4", + "token": "punctuation.definition.inserted" + }, + { + "foreground": "b08800", + "background": "fffdef", + "token": "markup.changed" + }, + { + "foreground": "b08800", + "background": "fffdef", + "token": "punctuation.definition.changed" + }, + { + "foreground": "2f363d", + "background": "959da5", + "token": "markup.ignored" + }, + { + "foreground": "2f363d", + "background": "959da5", + "token": "markup.untracked" + }, + { + "foreground": "b392f0", + "fontStyle": "bold", + "token": "meta.diff.range" + }, + { + "foreground": "c8e1ff", + "token": "meta.diff.header" + }, + { + "foreground": "0366d6", + "fontStyle": "bold", + "token": "meta.separator" + }, + { + "foreground": "0366d6", + "token": "meta.output" + }, + { + "foreground": "ffeef0", + "token": "brackethighlighter.tag" + }, + { + "foreground": "ffeef0", + "token": "brackethighlighter.curly" + }, + { + "foreground": "ffeef0", + "token": "brackethighlighter.round" + }, + { + "foreground": "ffeef0", + "token": "brackethighlighter.square" + }, + { + "foreground": "ffeef0", + "token": "brackethighlighter.angle" + }, + { + "foreground": "ffeef0", + "token": "brackethighlighter.quote" + }, + { + "foreground": "d73a49", + "token": "brackethighlighter.unmatched" + }, + { + "foreground": "d73a49", + "token": "sublimelinter.mark.error" + }, + { + "foreground": "fb8532", + "token": "sublimelinter.mark.warning" + }, + { + "foreground": "6a737d", + "token": "sublimelinter.gutter-mark" + }, + { + "foreground": "79b8ff", + "fontStyle": "underline", + "token": "constant.other.reference.link" + }, + { + "foreground": "79b8ff", + "fontStyle": "underline", + "token": "string.other.link" + } + ], + "colors": { + "editor.foreground": "#f6f8fa", + "editor.background": "#24292e", + "editor.selectionBackground": "#4c2889", + "editor.inactiveSelectionBackground": "#444d56", + "editor.lineHighlightBackground": "#444d56", + "editorCursor.foreground": "#ffffff", + "editorWhitespace.foreground": "#6a737d", + "editorIndentGuide.background": "#6a737d", + "editorIndentGuide.activeBackground": "#f6f8fa", + "editor.selectionHighlightBorder": "#444d56" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/github-light.json b/apps/desktop/src/renderer/src/lib/editor-themes/github-light.json new file mode 100644 index 00000000..832996ec --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/github-light.json @@ -0,0 +1,348 @@ +{ + "base": "vs", + "inherit": true, + "rules": [ + { + "background": "ffffff", + "token": "" + }, + { + "foreground": "6a737d", + "token": "comment" + }, + { + "foreground": "6a737d", + "token": "punctuation.definition.comment" + }, + { + "foreground": "6a737d", + "token": "string.comment" + }, + { + "foreground": "005cc5", + "token": "constant" + }, + { + "foreground": "005cc5", + "token": "entity.name.constant" + }, + { + "foreground": "005cc5", + "token": "variable.other.constant" + }, + { + "foreground": "005cc5", + "token": "variable.language" + }, + { + "foreground": "6f42c1", + "token": "entity" + }, + { + "foreground": "6f42c1", + "token": "entity.name" + }, + { + "foreground": "24292e", + "token": "variable.parameter.function" + }, + { + "foreground": "22863a", + "token": "entity.name.tag" + }, + { + "foreground": "d73a49", + "token": "keyword" + }, + { + "foreground": "d73a49", + "token": "storage" + }, + { + "foreground": "d73a49", + "token": "storage.type" + }, + { + "foreground": "24292e", + "token": "storage.modifier.package" + }, + { + "foreground": "24292e", + "token": "storage.modifier.import" + }, + { + "foreground": "24292e", + "token": "storage.type.java" + }, + { + "foreground": "032f62", + "token": "string" + }, + { + "foreground": "032f62", + "token": "punctuation.definition.string" + }, + { + "foreground": "032f62", + "token": "string punctuation.section.embedded source" + }, + { + "foreground": "005cc5", + "token": "support" + }, + { + "foreground": "005cc5", + "token": "meta.property-name" + }, + { + "foreground": "e36209", + "token": "variable" + }, + { + "foreground": "24292e", + "token": "variable.other" + }, + { + "foreground": "b31d28", + "fontStyle": "bold italic underline", + "token": "invalid.broken" + }, + { + "foreground": "b31d28", + "fontStyle": "bold italic underline", + "token": "invalid.deprecated" + }, + { + "foreground": "fafbfc", + "background": "b31d28", + "fontStyle": "italic underline", + "token": "invalid.illegal" + }, + { + "foreground": "fafbfc", + "background": "d73a49", + "fontStyle": "italic underline", + "token": "carriage-return" + }, + { + "foreground": "b31d28", + "fontStyle": "bold italic underline", + "token": "invalid.unimplemented" + }, + { + "foreground": "b31d28", + "token": "message.error" + }, + { + "foreground": "24292e", + "token": "string source" + }, + { + "foreground": "005cc5", + "token": "string variable" + }, + { + "foreground": "032f62", + "token": "source.regexp" + }, + { + "foreground": "032f62", + "token": "string.regexp" + }, + { + "foreground": "032f62", + "token": "string.regexp.character-class" + }, + { + "foreground": "032f62", + "token": "string.regexp constant.character.escape" + }, + { + "foreground": "032f62", + "token": "string.regexp source.ruby.embedded" + }, + { + "foreground": "032f62", + "token": "string.regexp string.regexp.arbitrary-repitition" + }, + { + "foreground": "22863a", + "fontStyle": "bold", + "token": "string.regexp constant.character.escape" + }, + { + "foreground": "005cc5", + "token": "support.constant" + }, + { + "foreground": "005cc5", + "token": "support.variable" + }, + { + "foreground": "005cc5", + "token": "meta.module-reference" + }, + { + "foreground": "735c0f", + "token": "markup.list" + }, + { + "foreground": "005cc5", + "fontStyle": "bold", + "token": "markup.heading" + }, + { + "foreground": "005cc5", + "fontStyle": "bold", + "token": "markup.heading entity.name" + }, + { + "foreground": "22863a", + "token": "markup.quote" + }, + { + "foreground": "24292e", + "fontStyle": "italic", + "token": "markup.italic" + }, + { + "foreground": "24292e", + "fontStyle": "bold", + "token": "markup.bold" + }, + { + "foreground": "005cc5", + "token": "markup.raw" + }, + { + "foreground": "b31d28", + "background": "ffeef0", + "token": "markup.deleted" + }, + { + "foreground": "b31d28", + "background": "ffeef0", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "b31d28", + "background": "ffeef0", + "token": "punctuation.definition.deleted" + }, + { + "foreground": "22863a", + "background": "f0fff4", + "token": "markup.inserted" + }, + { + "foreground": "22863a", + "background": "f0fff4", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "22863a", + "background": "f0fff4", + "token": "punctuation.definition.inserted" + }, + { + "foreground": "e36209", + "background": "ffebda", + "token": "markup.changed" + }, + { + "foreground": "e36209", + "background": "ffebda", + "token": "punctuation.definition.changed" + }, + { + "foreground": "f6f8fa", + "background": "005cc5", + "token": "markup.ignored" + }, + { + "foreground": "f6f8fa", + "background": "005cc5", + "token": "markup.untracked" + }, + { + "foreground": "6f42c1", + "fontStyle": "bold", + "token": "meta.diff.range" + }, + { + "foreground": "005cc5", + "token": "meta.diff.header" + }, + { + "foreground": "005cc5", + "fontStyle": "bold", + "token": "meta.separator" + }, + { + "foreground": "005cc5", + "token": "meta.output" + }, + { + "foreground": "586069", + "token": "brackethighlighter.tag" + }, + { + "foreground": "586069", + "token": "brackethighlighter.curly" + }, + { + "foreground": "586069", + "token": "brackethighlighter.round" + }, + { + "foreground": "586069", + "token": "brackethighlighter.square" + }, + { + "foreground": "586069", + "token": "brackethighlighter.angle" + }, + { + "foreground": "586069", + "token": "brackethighlighter.quote" + }, + { + "foreground": "b31d28", + "token": "brackethighlighter.unmatched" + }, + { + "foreground": "b31d28", + "token": "sublimelinter.mark.error" + }, + { + "foreground": "e36209", + "token": "sublimelinter.mark.warning" + }, + { + "foreground": "959da5", + "token": "sublimelinter.gutter-mark" + }, + { + "foreground": "032f62", + "fontStyle": "underline", + "token": "constant.other.reference.link" + }, + { + "foreground": "032f62", + "fontStyle": "underline", + "token": "string.other.link" + } + ], + "colors": { + "editor.foreground": "#24292e", + "editor.background": "#ffffff", + "editor.selectionBackground": "#c8c8fa", + "editor.inactiveSelectionBackground": "#fafbfc", + "editor.lineHighlightBackground": "#fafbfc", + "editorCursor.foreground": "#24292e", + "editorWhitespace.foreground": "#959da5", + "editorIndentGuide.background": "#959da5", + "editorIndentGuide.activeBackground": "#24292e", + "editor.selectionHighlightBorder": "#fafbfc" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/light-2026.json b/apps/desktop/src/renderer/src/lib/editor-themes/light-2026.json new file mode 100644 index 00000000..a3702d6d --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/light-2026.json @@ -0,0 +1,1471 @@ +{ + "base": "vs", + "inherit": true, + "rules": [ + { + "token": "meta.embedded", + "foreground": "000000" + }, + { + "token": "source.groovy.embedded", + "foreground": "000000" + }, + { + "token": "string meta.image.inline.markdown", + "foreground": "000000" + }, + { + "token": "variable.legacy.builtin.python", + "foreground": "000000" + }, + { + "token": "emphasis", + "fontStyle": "italic" + }, + { + "token": "strong", + "fontStyle": "bold" + }, + { + "token": "meta.diff.header", + "foreground": "000080" + }, + { + "token": "comment", + "foreground": "008000" + }, + { + "token": "constant.language", + "foreground": "0000ff" + }, + { + "token": "constant.numeric", + "foreground": "098658" + }, + { + "token": "variable.other.enummember", + "foreground": "098658" + }, + { + "token": "keyword.operator.plus.exponent", + "foreground": "098658" + }, + { + "token": "keyword.operator.minus.exponent", + "foreground": "098658" + }, + { + "token": "constant.regexp", + "foreground": "811f3f" + }, + { + "token": "entity.name.tag", + "foreground": "800000" + }, + { + "token": "entity.name.selector", + "foreground": "800000" + }, + { + "token": "entity.other.attribute-name", + "foreground": "e50000" + }, + { + "token": "entity.other.attribute-name.class.css", + "foreground": "800000" + }, + { + "token": "source.css entity.other.attribute-name.class", + "foreground": "800000" + }, + { + "token": "entity.other.attribute-name.id.css", + "foreground": "800000" + }, + { + "token": "entity.other.attribute-name.parent-selector.css", + "foreground": "800000" + }, + { + "token": "entity.other.attribute-name.parent.less", + "foreground": "800000" + }, + { + "token": "source.css entity.other.attribute-name.pseudo-class", + "foreground": "800000" + }, + { + "token": "entity.other.attribute-name.pseudo-element.css", + "foreground": "800000" + }, + { + "token": "source.css.less entity.other.attribute-name.id", + "foreground": "800000" + }, + { + "token": "entity.other.attribute-name.scss", + "foreground": "800000" + }, + { + "token": "invalid", + "foreground": "cd3131" + }, + { + "token": "markup.underline", + "fontStyle": "underline" + }, + { + "token": "markup.bold", + "foreground": "000080", + "fontStyle": "bold" + }, + { + "token": "markup.heading", + "foreground": "800000", + "fontStyle": "bold" + }, + { + "token": "markup.italic", + "foreground": "800080", + "fontStyle": "italic" + }, + { + "token": "markup.strikethrough", + "fontStyle": "strikethrough" + }, + { + "token": "markup.inserted", + "foreground": "098658" + }, + { + "token": "markup.deleted", + "foreground": "a31515" + }, + { + "token": "markup.changed", + "foreground": "0451a5" + }, + { + "token": "punctuation.definition.quote.begin.markdown", + "foreground": "0451a5" + }, + { + "token": "punctuation.definition.list.begin.markdown", + "foreground": "0451a5" + }, + { + "token": "markup.inline.raw", + "foreground": "800000" + }, + { + "token": "punctuation.definition.tag", + "foreground": "800000" + }, + { + "token": "meta.preprocessor", + "foreground": "0000ff" + }, + { + "token": "entity.name.function.preprocessor", + "foreground": "0000ff" + }, + { + "token": "meta.preprocessor.string", + "foreground": "a31515" + }, + { + "token": "meta.preprocessor.numeric", + "foreground": "098658" + }, + { + "token": "meta.structure.dictionary.key.python", + "foreground": "0451a5" + }, + { + "token": "storage", + "foreground": "0000ff" + }, + { + "token": "storage.type", + "foreground": "0000ff" + }, + { + "token": "storage.modifier", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.noexcept", + "foreground": "0000ff" + }, + { + "token": "string", + "foreground": "a31515" + }, + { + "token": "meta.embedded.assembly", + "foreground": "a31515" + }, + { + "token": "string.comment.buffered.block.pug", + "foreground": "0000ff" + }, + { + "token": "string.quoted.pug", + "foreground": "0000ff" + }, + { + "token": "string.interpolated.pug", + "foreground": "0000ff" + }, + { + "token": "string.unquoted.plain.in.yaml", + "foreground": "0000ff" + }, + { + "token": "string.unquoted.plain.out.yaml", + "foreground": "0000ff" + }, + { + "token": "string.unquoted.block.yaml", + "foreground": "0000ff" + }, + { + "token": "string.quoted.single.yaml", + "foreground": "0000ff" + }, + { + "token": "string.quoted.double.xml", + "foreground": "0000ff" + }, + { + "token": "string.quoted.single.xml", + "foreground": "0000ff" + }, + { + "token": "string.unquoted.cdata.xml", + "foreground": "0000ff" + }, + { + "token": "string.quoted.double.html", + "foreground": "0000ff" + }, + { + "token": "string.quoted.single.html", + "foreground": "0000ff" + }, + { + "token": "string.unquoted.html", + "foreground": "0000ff" + }, + { + "token": "string.quoted.single.handlebars", + "foreground": "0000ff" + }, + { + "token": "string.quoted.double.handlebars", + "foreground": "0000ff" + }, + { + "token": "string.regexp", + "foreground": "811f3f" + }, + { + "token": "punctuation.definition.template-expression.begin", + "foreground": "0000ff" + }, + { + "token": "punctuation.definition.template-expression.end", + "foreground": "0000ff" + }, + { + "token": "punctuation.section.embedded", + "foreground": "0000ff" + }, + { + "token": "meta.template.expression", + "foreground": "000000" + }, + { + "token": "support.constant.property-value", + "foreground": "0451a5" + }, + { + "token": "support.constant.font-name", + "foreground": "0451a5" + }, + { + "token": "support.constant.media-type", + "foreground": "0451a5" + }, + { + "token": "support.constant.media", + "foreground": "0451a5" + }, + { + "token": "constant.other.color.rgb-value", + "foreground": "0451a5" + }, + { + "token": "constant.other.rgb-value", + "foreground": "0451a5" + }, + { + "token": "support.constant.color", + "foreground": "0451a5" + }, + { + "token": "support.type.vendored.property-name", + "foreground": "e50000" + }, + { + "token": "support.type.property-name", + "foreground": "e50000" + }, + { + "token": "source.css variable", + "foreground": "e50000" + }, + { + "token": "source.coffee.embedded", + "foreground": "e50000" + }, + { + "token": "support.type.property-name.json", + "foreground": "0451a5" + }, + { + "token": "keyword", + "foreground": "0000ff" + }, + { + "token": "keyword.control", + "foreground": "0000ff" + }, + { + "token": "keyword.operator", + "foreground": "000000" + }, + { + "token": "keyword.operator.new", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.expression", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.cast", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.sizeof", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.alignof", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.typeid", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.alignas", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.instanceof", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.logical.python", + "foreground": "0000ff" + }, + { + "token": "keyword.operator.wordlike", + "foreground": "0000ff" + }, + { + "token": "keyword.other.unit", + "foreground": "098658" + }, + { + "token": "punctuation.section.embedded.begin.php", + "foreground": "800000" + }, + { + "token": "punctuation.section.embedded.end.php", + "foreground": "800000" + }, + { + "token": "support.function.git-rebase", + "foreground": "0451a5" + }, + { + "token": "constant.sha.git-rebase", + "foreground": "098658" + }, + { + "token": "storage.modifier.import.java", + "foreground": "000000" + }, + { + "token": "variable.language.wildcard.java", + "foreground": "000000" + }, + { + "token": "storage.modifier.package.java", + "foreground": "000000" + }, + { + "token": "variable.language", + "foreground": "0000ff" + }, + { + "token": "entity.name.function", + "foreground": "795E26" + }, + { + "token": "support.function", + "foreground": "795E26" + }, + { + "token": "support.constant.handlebars", + "foreground": "795E26" + }, + { + "token": "source.powershell variable.other.member", + "foreground": "795E26" + }, + { + "token": "entity.name.operator.custom-literal", + "foreground": "795E26" + }, + { + "token": "support.class", + "foreground": "267f99" + }, + { + "token": "support.type", + "foreground": "267f99" + }, + { + "token": "entity.name.type", + "foreground": "267f99" + }, + { + "token": "entity.name.namespace", + "foreground": "267f99" + }, + { + "token": "entity.other.attribute", + "foreground": "267f99" + }, + { + "token": "entity.name.scope-resolution", + "foreground": "267f99" + }, + { + "token": "entity.name.class", + "foreground": "267f99" + }, + { + "token": "storage.type.numeric.go", + "foreground": "267f99" + }, + { + "token": "storage.type.byte.go", + "foreground": "267f99" + }, + { + "token": "storage.type.boolean.go", + "foreground": "267f99" + }, + { + "token": "storage.type.string.go", + "foreground": "267f99" + }, + { + "token": "storage.type.uintptr.go", + "foreground": "267f99" + }, + { + "token": "storage.type.error.go", + "foreground": "267f99" + }, + { + "token": "storage.type.rune.go", + "foreground": "267f99" + }, + { + "token": "storage.type.cs", + "foreground": "267f99" + }, + { + "token": "storage.type.generic.cs", + "foreground": "267f99" + }, + { + "token": "storage.type.modifier.cs", + "foreground": "267f99" + }, + { + "token": "storage.type.variable.cs", + "foreground": "267f99" + }, + { + "token": "storage.type.annotation.java", + "foreground": "267f99" + }, + { + "token": "storage.type.generic.java", + "foreground": "267f99" + }, + { + "token": "storage.type.java", + "foreground": "267f99" + }, + { + "token": "storage.type.object.array.java", + "foreground": "267f99" + }, + { + "token": "storage.type.primitive.array.java", + "foreground": "267f99" + }, + { + "token": "storage.type.primitive.java", + "foreground": "267f99" + }, + { + "token": "storage.type.token.java", + "foreground": "267f99" + }, + { + "token": "storage.type.groovy", + "foreground": "267f99" + }, + { + "token": "storage.type.annotation.groovy", + "foreground": "267f99" + }, + { + "token": "storage.type.parameters.groovy", + "foreground": "267f99" + }, + { + "token": "storage.type.generic.groovy", + "foreground": "267f99" + }, + { + "token": "storage.type.object.array.groovy", + "foreground": "267f99" + }, + { + "token": "storage.type.primitive.array.groovy", + "foreground": "267f99" + }, + { + "token": "storage.type.primitive.groovy", + "foreground": "267f99" + }, + { + "token": "meta.type.cast.expr", + "foreground": "267f99" + }, + { + "token": "meta.type.new.expr", + "foreground": "267f99" + }, + { + "token": "support.constant.math", + "foreground": "267f99" + }, + { + "token": "support.constant.dom", + "foreground": "267f99" + }, + { + "token": "support.constant.json", + "foreground": "267f99" + }, + { + "token": "entity.other.inherited-class", + "foreground": "267f99" + }, + { + "token": "punctuation.separator.namespace.ruby", + "foreground": "267f99" + }, + { + "token": "keyword.control", + "foreground": "AF00DB" + }, + { + "token": "source.cpp keyword.operator.new", + "foreground": "AF00DB" + }, + { + "token": "source.cpp keyword.operator.delete", + "foreground": "AF00DB" + }, + { + "token": "keyword.other.using", + "foreground": "AF00DB" + }, + { + "token": "keyword.other.directive.using", + "foreground": "AF00DB" + }, + { + "token": "keyword.other.operator", + "foreground": "AF00DB" + }, + { + "token": "entity.name.operator", + "foreground": "AF00DB" + }, + { + "token": "variable", + "foreground": "001080" + }, + { + "token": "meta.definition.variable.name", + "foreground": "001080" + }, + { + "token": "support.variable", + "foreground": "001080" + }, + { + "token": "entity.name.variable", + "foreground": "001080" + }, + { + "token": "constant.other.placeholder", + "foreground": "001080" + }, + { + "token": "variable.other.constant", + "foreground": "0070C1" + }, + { + "token": "variable.other.enummember", + "foreground": "0070C1" + }, + { + "token": "meta.object-literal.key", + "foreground": "001080" + }, + { + "token": "support.constant.property-value", + "foreground": "0451a5" + }, + { + "token": "support.constant.font-name", + "foreground": "0451a5" + }, + { + "token": "support.constant.media-type", + "foreground": "0451a5" + }, + { + "token": "support.constant.media", + "foreground": "0451a5" + }, + { + "token": "constant.other.color.rgb-value", + "foreground": "0451a5" + }, + { + "token": "constant.other.rgb-value", + "foreground": "0451a5" + }, + { + "token": "support.constant.color", + "foreground": "0451a5" + }, + { + "token": "punctuation.definition.group.regexp", + "foreground": "d16969" + }, + { + "token": "punctuation.definition.group.assertion.regexp", + "foreground": "d16969" + }, + { + "token": "punctuation.definition.character-class.regexp", + "foreground": "d16969" + }, + { + "token": "punctuation.character.set.begin.regexp", + "foreground": "d16969" + }, + { + "token": "punctuation.character.set.end.regexp", + "foreground": "d16969" + }, + { + "token": "keyword.operator.negation.regexp", + "foreground": "d16969" + }, + { + "token": "support.other.parenthesis.regexp", + "foreground": "d16969" + }, + { + "token": "constant.character.character-class.regexp", + "foreground": "811f3f" + }, + { + "token": "constant.other.character-class.set.regexp", + "foreground": "811f3f" + }, + { + "token": "constant.other.character-class.regexp", + "foreground": "811f3f" + }, + { + "token": "constant.character.set.regexp", + "foreground": "811f3f" + }, + { + "token": "keyword.operator.quantifier.regexp", + "foreground": "000000" + }, + { + "token": "keyword.operator.or.regexp", + "foreground": "EE0000" + }, + { + "token": "keyword.control.anchor.regexp", + "foreground": "EE0000" + }, + { + "token": "constant.character", + "foreground": "0000ff" + }, + { + "token": "constant.other.option", + "foreground": "0000ff" + }, + { + "token": "constant.character.escape", + "foreground": "EE0000" + }, + { + "token": "entity.name.label", + "foreground": "000000" + }, + { + "token": "comment", + "foreground": "6e7781" + }, + { + "token": "punctuation.definition.comment", + "foreground": "6e7781" + }, + { + "token": "string.comment", + "foreground": "6e7781" + }, + { + "token": "constant.other.placeholder", + "foreground": "cf222e" + }, + { + "token": "constant.character", + "foreground": "cf222e" + }, + { + "token": "constant", + "foreground": "0550ae" + }, + { + "token": "entity.name.constant", + "foreground": "0550ae" + }, + { + "token": "variable.other.constant", + "foreground": "0550ae" + }, + { + "token": "variable.other.enummember", + "foreground": "0550ae" + }, + { + "token": "variable.language", + "foreground": "0550ae" + }, + { + "token": "entity", + "foreground": "0550ae" + }, + { + "token": "entity.name", + "foreground": "953800" + }, + { + "token": "meta.export.default", + "foreground": "953800" + }, + { + "token": "meta.definition.variable", + "foreground": "953800" + }, + { + "token": "variable.parameter.function", + "foreground": "1f2328" + }, + { + "token": "meta.jsx.children", + "foreground": "1f2328" + }, + { + "token": "meta.block", + "foreground": "1f2328" + }, + { + "token": "meta.tag.attributes", + "foreground": "1f2328" + }, + { + "token": "entity.name.constant", + "foreground": "1f2328" + }, + { + "token": "meta.object.member", + "foreground": "1f2328" + }, + { + "token": "meta.embedded.expression", + "foreground": "1f2328" + }, + { + "token": "entity.name.function", + "foreground": "8250df" + }, + { + "token": "entity.name.tag", + "foreground": "116329" + }, + { + "token": "support.class.component", + "foreground": "116329" + }, + { + "token": "keyword", + "foreground": "cf222e" + }, + { + "token": "storage", + "foreground": "cf222e" + }, + { + "token": "storage.type", + "foreground": "cf222e" + }, + { + "token": "storage.modifier.package", + "foreground": "1f2328" + }, + { + "token": "storage.modifier.import", + "foreground": "1f2328" + }, + { + "token": "storage.type.java", + "foreground": "1f2328" + }, + { + "token": "string", + "foreground": "0a3069" + }, + { + "token": "string punctuation.section.embedded source", + "foreground": "0a3069" + }, + { + "token": "support", + "foreground": "0550ae" + }, + { + "token": "meta.property-name", + "foreground": "0550ae" + }, + { + "token": "variable", + "foreground": "953800" + }, + { + "token": "variable.other", + "foreground": "1f2328" + }, + { + "token": "invalid.broken", + "foreground": "82071e", + "fontStyle": "italic" + }, + { + "token": "invalid.deprecated", + "foreground": "82071e", + "fontStyle": "italic" + }, + { + "token": "invalid.illegal", + "foreground": "82071e", + "fontStyle": "italic" + }, + { + "token": "invalid.unimplemented", + "foreground": "82071e", + "fontStyle": "italic" + }, + { + "token": "carriage-return", + "foreground": "f6f8fa", + "background": "cf222e", + "fontStyle": "italic underline" + }, + { + "token": "message.error", + "foreground": "82071e" + }, + { + "token": "string variable", + "foreground": "0550ae" + }, + { + "token": "source.regexp", + "foreground": "0a3069" + }, + { + "token": "string.regexp", + "foreground": "0a3069" + }, + { + "token": "string.regexp.character-class", + "foreground": "0a3069" + }, + { + "token": "string.regexp constant.character.escape", + "foreground": "0a3069" + }, + { + "token": "string.regexp source.ruby.embedded", + "foreground": "0a3069" + }, + { + "token": "string.regexp string.regexp.arbitrary-repitition", + "foreground": "0a3069" + }, + { + "token": "string.regexp constant.character.escape", + "foreground": "116329", + "fontStyle": "bold" + }, + { + "token": "support.constant", + "foreground": "0550ae" + }, + { + "token": "support.variable", + "foreground": "0550ae" + }, + { + "token": "support.type.property-name.json", + "foreground": "116329" + }, + { + "token": "meta.module-reference", + "foreground": "0550ae" + }, + { + "token": "punctuation.definition.list.begin.markdown", + "foreground": "953800" + }, + { + "token": "markup.heading", + "foreground": "0550ae", + "fontStyle": "bold" + }, + { + "token": "markup.heading entity.name", + "foreground": "0550ae", + "fontStyle": "bold" + }, + { + "token": "markup.quote", + "foreground": "116329" + }, + { + "token": "markup.italic", + "foreground": "1f2328", + "fontStyle": "italic" + }, + { + "token": "markup.bold", + "foreground": "1f2328", + "fontStyle": "bold" + }, + { + "token": "markup.underline", + "fontStyle": "underline" + }, + { + "token": "markup.strikethrough", + "fontStyle": "strikethrough" + }, + { + "token": "markup.inline.raw", + "foreground": "0550ae" + }, + { + "token": "markup.deleted", + "foreground": "82071e", + "background": "ffebe9" + }, + { + "token": "meta.diff.header.from-file", + "foreground": "82071e", + "background": "ffebe9" + }, + { + "token": "punctuation.definition.deleted", + "foreground": "82071e", + "background": "ffebe9" + }, + { + "token": "punctuation.section.embedded", + "foreground": "cf222e" + }, + { + "token": "markup.inserted", + "foreground": "116329", + "background": "dafbe1" + }, + { + "token": "meta.diff.header.to-file", + "foreground": "116329", + "background": "dafbe1" + }, + { + "token": "punctuation.definition.inserted", + "foreground": "116329", + "background": "dafbe1" + }, + { + "token": "markup.changed", + "foreground": "953800", + "background": "ffd8b5" + }, + { + "token": "punctuation.definition.changed", + "foreground": "953800", + "background": "ffd8b5" + }, + { + "token": "markup.ignored", + "foreground": "eaeef2", + "background": "0550ae" + }, + { + "token": "markup.untracked", + "foreground": "eaeef2", + "background": "0550ae" + }, + { + "token": "meta.diff.range", + "foreground": "8250df", + "fontStyle": "bold" + }, + { + "token": "meta.diff.header", + "foreground": "0550ae" + }, + { + "token": "meta.separator", + "foreground": "0550ae", + "fontStyle": "bold" + }, + { + "token": "meta.output", + "foreground": "0550ae" + }, + { + "token": "brackethighlighter.tag", + "foreground": "57606a" + }, + { + "token": "brackethighlighter.curly", + "foreground": "57606a" + }, + { + "token": "brackethighlighter.round", + "foreground": "57606a" + }, + { + "token": "brackethighlighter.square", + "foreground": "57606a" + }, + { + "token": "brackethighlighter.angle", + "foreground": "57606a" + }, + { + "token": "brackethighlighter.quote", + "foreground": "57606a" + }, + { + "token": "brackethighlighter.unmatched", + "foreground": "82071e" + }, + { + "token": "constant.other.reference.link", + "foreground": "0a3069" + }, + { + "token": "string.other.link", + "foreground": "0a3069" + } + ], + "colors": { + "checkbox.border": "#868686", + "editor.background": "#FFFFFF", + "editor.foreground": "#202020", + "editor.inactiveSelectionBackground": "#0069CC1A", + "editorIndentGuide.background1": "#D3D3D3", + "editorIndentGuide.activeBackground1": "#939393", + "editor.selectionHighlightBackground": "#0069CC15", + "editorSuggestWidget.background": "#FAFAFD", + "activityBarBadge.background": "#0069CC", + "sideBarTitle.foreground": "#202020", + "list.hoverBackground": "#F1F1F3", + "menu.border": "#E4E5E6FF", + "input.placeholderForeground": "#999999", + "searchEditor.textInputBorder": "#CECECE", + "settings.textInputBorder": "#CECECE", + "settings.numberInputBorder": "#CECECE", + "statusBarItem.remoteForeground": "#FFFFFF", + "statusBarItem.remoteBackground": "#005FB8", + "ports.iconRunningProcessForeground": "#369432", + "sideBarSectionHeader.background": "#FAFAFD", + "sideBarSectionHeader.border": "#F0F1F2FF", + "tab.selectedForeground": "#333333b3", + "tab.selectedBackground": "#ffffffa5", + "tab.lastPinnedBorder": "#F0F1F2FF", + "notebook.cellBorderColor": "#E5E5E5", + "notebook.selectedCellBackground": "#C8DDF150", + "statusBarItem.errorBackground": "#C72E0F", + "list.activeSelectionIconForeground": "#000000", + "list.focusAndSelectionOutline": "#005FB8", + "terminal.inactiveSelectionBackground": "#E5EBF1", + "widget.border": "#E2E2E5", + "actionBar.toggledBackground": "#dddddd", + "diffEditor.unchangedRegionBackground": "#f8f8f8", + "agentsNewSessionButton.border": "#D8D8D8", + "agentsChatInput.border": "#D8D8D8", + "activityBar.activeBorder": "#000000", + "activityBar.background": "#FAFAFD", + "activityBar.border": "#F0F1F2FF", + "activityBar.foreground": "#202020", + "activityBar.inactiveForeground": "#606060", + "activityBarBadge.foreground": "#FFFFFF", + "badge.background": "#0069CC", + "badge.foreground": "#FFFFFF", + "button.background": "#0069CC", + "button.border": "#0069CC", + "button.foreground": "#FFFFFF", + "button.hoverBackground": "#0063C1", + "button.secondaryBackground": "#EAEAEA", + "button.secondaryForeground": "#202020", + "button.secondaryHoverBackground": "#F2F3F4", + "chat.slashCommandBackground": "#ADCEFF7A", + "chat.slashCommandForeground": "#26569E", + "chat.editedFileForeground": "#895503", + "checkbox.background": "#EAEAEA", + "descriptionForeground": "#606060", + "dropdown.background": "#FFFFFF", + "dropdown.border": "#D8D8D8", + "dropdown.foreground": "#202020", + "dropdown.listBackground": "#FFFFFF", + "editorGroup.border": "#E5E5E5", + "editorGroupHeader.tabsBackground": "#FAFAFD", + "editorGroupHeader.tabsBorder": "#F0F1F2FF", + "editorGutter.addedBackground": "#587c0c", + "editorGutter.deletedBackground": "#ad0707", + "editorGutter.modifiedBackground": "#005FB8", + "editorLineNumber.activeForeground": "#202020", + "editorLineNumber.foreground": "#606060", + "editorOverviewRuler.border": "#F0F1F2FF", + "editorWidget.background": "#FAFAFD", + "errorForeground": "#ad0707", + "focusBorder": "#0069CCFF", + "foreground": "#202020", + "icon.foreground": "#606060", + "input.background": "#FFFFFF", + "input.border": "#D8D8D866", + "input.foreground": "#202020", + "inputOption.activeBackground": "#0069CC26", + "inputOption.activeBorder": "#F0F1F2FF", + "inputOption.activeForeground": "#202020", + "keybindingLabel.foreground": "#3B3B3B", + "list.activeSelectionBackground": "#0069CC1A", + "list.activeSelectionForeground": "#202020", + "menu.selectionBackground": "#0069CC1A", + "menu.selectionForeground": "#202020", + "notificationCenterHeader.background": "#FAFAFD", + "notificationCenterHeader.foreground": "#202020", + "notifications.background": "#FAFAFD", + "notifications.border": "#F0F1F2FF", + "notifications.foreground": "#202020", + "panel.background": "#FAFAFD", + "panel.border": "#F0F1F2FF", + "panelInput.border": "#E5E5E5", + "panelTitle.activeBorder": "#000000", + "panelTitle.activeForeground": "#202020", + "panelTitle.inactiveForeground": "#606060", + "peekViewEditor.matchHighlightBackground": "#0069CC33", + "peekViewResult.background": "#FAFAFD", + "peekViewResult.matchHighlightBackground": "#0069CC33", + "pickerGroup.border": "#EEEEF1", + "pickerGroup.foreground": "#202020", + "progressBar.background": "#0069CC", + "quickInput.background": "#FAFAFD", + "quickInput.foreground": "#202020", + "settings.dropdownBackground": "#FFFFFF", + "settings.dropdownBorder": "#CECECE", + "settings.headerForeground": "#1F1F1F", + "settings.modifiedItemIndicator": "#BB800966", + "sideBar.background": "#FAFAFD", + "sideBar.border": "#F0F1F2FF", + "sideBar.foreground": "#202020", + "sideBarSectionHeader.foreground": "#202020", + "statusBar.background": "#FAFAFD", + "statusBar.foreground": "#606060", + "statusBar.border": "#F0F1F2FF", + "statusBarItem.hoverBackground": "#E3E3E5", + "statusBarItem.hoverForeground": "#000000", + "statusBarItem.compactHoverBackground": "#CCCCCC", + "statusBar.debuggingBackground": "#0069CC", + "statusBar.debuggingForeground": "#FFFFFF", + "statusBar.focusBorder": "#0069CCFF", + "statusBar.noFolderBackground": "#F0F0F3", + "statusBarItem.focusBorder": "#0069CCFF", + "statusBarItem.prominentBackground": "#0069CCDD", + "tab.activeBackground": "#FFFFFF", + "tab.activeBorder": "#FFFFFF", + "tab.activeBorderTop": "#000000", + "tab.activeForeground": "#202020", + "tab.selectedBorderTop": "#68a3da", + "tab.border": "#F0F1F2FF", + "tab.hoverBackground": "#FFFFFF", + "tab.inactiveBackground": "#FAFAFD", + "tab.inactiveForeground": "#606060", + "tab.unfocusedActiveBorder": "#F8F8F8", + "tab.unfocusedActiveBorderTop": "#E5E5E5", + "tab.unfocusedHoverBackground": "#F8F8F8", + "terminalCursor.foreground": "#202020", + "terminal.foreground": "#3B3B3B", + "terminal.tab.activeBorder": "#005FB8", + "textBlockQuote.background": "#EAEAEA", + "textBlockQuote.border": "#F0F1F2FF", + "textCodeBlock.background": "#EAEAEA", + "textLink.activeForeground": "#0069CC", + "textLink.foreground": "#0069CC", + "textPreformat.foreground": "#606060", + "textPreformat.background": "#ECECEC", + "textSeparator.foreground": "#EEEEEEFF", + "titleBar.activeBackground": "#FAFAFD", + "titleBar.activeForeground": "#606060", + "titleBar.border": "#F0F1F2FF", + "titleBar.inactiveBackground": "#FAFAFD", + "titleBar.inactiveForeground": "#606060", + "welcomePage.tileBackground": "#F3F3F3", + "disabledForeground": "#BBBBBB", + "button.secondaryBorder": "#EAEAEA", + "checkbox.foreground": "#606060", + "inputValidation.infoBackground": "#E6F2FA", + "inputValidation.infoBorder": "#0069CC", + "inputValidation.infoForeground": "#202020", + "inputValidation.warningBackground": "#FDF6E3", + "inputValidation.warningBorder": "#B69500", + "inputValidation.warningForeground": "#202020", + "inputValidation.errorBackground": "#FDEDED", + "inputValidation.errorBorder": "#ad0707", + "inputValidation.errorForeground": "#202020", + "scrollbar.shadow": "#00000000", + "widget.shadow": "#00000000", + "editorStickyScroll.shadow": "#00000000", + "editorStickyScrollHover.background": "#F0F0F3", + "editorStickyScroll.border": "#F0F1F2FF", + "sideBarStickyScroll.shadow": "#00000000", + "panelStickyScroll.shadow": "#00000000", + "listFilterWidget.shadow": "#00000000", + "scrollbarSlider.background": "#64646480", + "scrollbarSlider.hoverBackground": "#64646490", + "scrollbarSlider.activeBackground": "#646464A0", + "list.inactiveSelectionBackground": "#DADADA99", + "list.inactiveSelectionForeground": "#202020", + "list.hoverForeground": "#202020", + "list.dropBackground": "#0069CC15", + "list.focusBackground": "#0069CC1A", + "list.focusForeground": "#202020", + "list.focusOutline": "#0069CCFF", + "list.highlightForeground": "#0069CC", + "list.invalidItemForeground": "#BBBBBB", + "list.errorForeground": "#ad0707", + "list.warningForeground": "#667309", + "activityBar.activeFocusBorder": "#0069CCFF", + "activityBarTop.activeBorder": "#000000", + "menubar.selectionBackground": "#EAEAEA", + "menubar.selectionForeground": "#202020", + "menu.background": "#FAFAFD", + "menu.foreground": "#202020", + "menu.selectionBorder": "#0069CC", + "menu.separatorBackground": "#EEEEF1", + "commandCenter.foreground": "#202020", + "commandCenter.activeForeground": "#202020", + "commandCenter.background": "#FFFFFF", + "commandCenter.activeBackground": "#DADADA4f", + "commandCenter.border": "#D8D8D8AA", + "editorCursor.foreground": "#202020", + "editor.selectionBackground": "#0069CC40", + "editor.wordHighlightBackground": "#0069CC26", + "editor.wordHighlightStrongBackground": "#0069CC26", + "editor.findMatchBackground": "#0069CC40", + "editor.findMatchHighlightBackground": "#0069CC1A", + "editor.findRangeHighlightBackground": "#EAEAEA", + "editor.hoverHighlightBackground": "#EAEAEA", + "editor.lineHighlightBackground": "#EAEAEA40", + "editor.rangeHighlightBackground": "#EAEAEA", + "editorLink.activeForeground": "#0069CC", + "editorWhitespace.foreground": "#60606040", + "editorIndentGuide.background": "#F7F7F740", + "editorIndentGuide.activeBackground": "#EEEEEE", + "editorRuler.foreground": "#F7F7F7", + "editorCodeLens.foreground": "#606060", + "editorBracketMatch.background": "#0069CC40", + "editorBracketMatch.border": "#F0F1F2FF", + "editorWidget.border": "#E4E5E6FF", + "editorWidget.foreground": "#202020", + "editorSuggestWidget.border": "#E4E5E6FF", + "editorSuggestWidget.foreground": "#202020", + "editorSuggestWidget.highlightForeground": "#0069CC", + "editorSuggestWidget.selectedBackground": "#0069CC26", + "editorSuggestWidget.selectedForeground": "#202020", + "editorSuggestWidget.selectedIconForeground": "#202020", + "editorHoverWidget.background": "#FAFAFD", + "editorHoverWidget.border": "#E4E5E6FF", + "peekView.border": "#0069CC", + "peekViewEditor.background": "#FAFAFD", + "peekViewResult.fileForeground": "#202020", + "peekViewResult.lineForeground": "#606060", + "peekViewResult.selectionBackground": "#0069CC26", + "peekViewResult.selectionForeground": "#202020", + "peekViewTitle.background": "#FAFAFD", + "peekViewTitleDescription.foreground": "#606060", + "peekViewTitleLabel.foreground": "#202020", + "diffEditor.insertedTextBackground": "#587c0c26", + "diffEditor.removedTextBackground": "#ad070726", + "editorOverviewRuler.findMatchForeground": "#0069CC99", + "editorOverviewRuler.modifiedForeground": "#0069CC", + "editorOverviewRuler.addedForeground": "#587c0c", + "editorOverviewRuler.deletedForeground": "#ad0707", + "editorOverviewRuler.errorForeground": "#ad0707", + "editorOverviewRuler.warningForeground": "#667309", + "editorGutter.background": "#FFFFFF", + "statusBar.noFolderForeground": "#606060", + "statusBarItem.activeBackground": "#EEEEEE", + "statusBarItem.prominentForeground": "#FFFFFF", + "statusBarItem.prominentHoverBackground": "#0069CC", + "toolbar.hoverBackground": "#0000001F", + "toolbar.activeBackground": "#D6D6D8", + "tab.hoverForeground": "#202020", + "tab.unfocusedActiveBackground": "#FAFAFD", + "tab.unfocusedActiveForeground": "#606060", + "tab.unfocusedInactiveBackground": "#FAFAFD", + "tab.unfocusedInactiveForeground": "#BBBBBB", + "breadcrumb.foreground": "#606060", + "breadcrumb.background": "#FFFFFF", + "breadcrumb.focusForeground": "#202020", + "breadcrumb.activeSelectionForeground": "#202020", + "breadcrumbPicker.background": "#FAFAFD", + "notificationCenter.border": "#F0F1F2FF", + "notificationToast.border": "#F0F1F2FF", + "notificationLink.foreground": "#0069CC", + "notificationsWarningIcon.foreground": "#B69500", + "notificationsErrorIcon.foreground": "#ad0707", + "notificationsInfoIcon.foreground": "#0069CC", + "activityWarningBadge.foreground": "#202020", + "activityWarningBadge.background": "#F2C94C", + "activityErrorBadge.foreground": "#FFFFFF", + "activityErrorBadge.background": "#ad0707", + "extensionButton.prominentBackground": "#0069CC", + "extensionButton.prominentForeground": "#FFFFFF", + "extensionButton.prominentHoverBackground": "#0064CC", + "quickInputList.focusBackground": "#0069CC", + "quickInputList.focusForeground": "#FFFFFF", + "quickInputList.focusIconForeground": "#FFFFFF", + "quickInputList.focusHighlightForeground": "#FFFFFF", + "quickInputList.hoverBackground": "#F1F1F3", + "terminal.selectionBackground": "#0069CC26", + "terminalCursor.background": "#FFFFFF", + "gitDecoration.addedResourceForeground": "#587c0c", + "gitDecoration.modifiedResourceForeground": "#667309", + "gitDecoration.deletedResourceForeground": "#ad0707", + "gitDecoration.untrackedResourceForeground": "#587c0c", + "gitDecoration.ignoredResourceForeground": "#8E8E90", + "gitDecoration.conflictingResourceForeground": "#ad0707", + "gitDecoration.stageModifiedResourceForeground": "#667309", + "gitDecoration.stageDeletedResourceForeground": "#ad0707", + "commandCenter.activeBorder": "#D8D8D8", + "quickInput.border": "#D8D8D8", + "gauge.foreground": "#0069CC", + "gauge.background": "#0069CC40", + "gauge.border": "#F0F1F2FF", + "gauge.warningForeground": "#B69500", + "gauge.warningBackground": "#B6950040", + "gauge.errorForeground": "#ad0707", + "gauge.errorBackground": "#ad070740", + "statusBarItem.prominentHoverForeground": "#FFFFFF", + "quickInputTitle.background": "#FAFAFD", + "chat.requestBubbleBackground": "#EEF4FB", + "chat.requestBubbleHoverBackground": "#E6EDFA", + "chat.thinkingShimmer": "#999999", + "chat.inputWorkingBorderColor1": "#0069CC", + "chat.inputWorkingBorderColor2": "#004A99", + "chat.inputWorkingBorderColor3": "#3399E6", + "editorCommentsWidget.rangeBackground": "#EEF4FB", + "editorCommentsWidget.rangeActiveBackground": "#E6EDFA", + "charts.foreground": "#202020", + "charts.lines": "#20202066", + "charts.blue": "#1A5CFF", + "charts.red": "#ad0707", + "charts.yellow": "#667309", + "charts.orange": "#d18616", + "charts.green": "#388A34", + "charts.purple": "#652D90", + "agentStatusIndicator.background": "#FFFFFF", + "inlineChat.border": "#00000000", + "minimapSlider.background": "#64646480", + "minimapSlider.hoverBackground": "#64646490", + "minimapSlider.activeBackground": "#646464A0", + "agents.background": "#FAFAFD", + "agentsPanel.background": "#FFFFFF", + "agentsPanel.foreground": "#202020", + "agentsPanel.border": "#E4E5E6FF", + "agentsGradient.tintColor": "#0069CC", + "agentsChatInput.background": "#F7F7FA", + "agentsChatInput.foreground": "#202020", + "agentsChatInput.focusBorder": "#0069CCFF", + "agentsChatInput.placeholderForeground": "#999999", + "agentsNewSessionButton.background": "#00000000", + "agentsNewSessionButton.foreground": "#202020", + "agentsNewSessionButton.hoverBackground": "#00000010", + "agentsBadge.background": "#0069CC", + "agentsBadge.foreground": "#FFFFFF", + "agentsUnreadBadge.background": "#0069CC", + "agentsUnreadBadge.foreground": "#FFFFFF" + } +} diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/monokai.json b/apps/desktop/src/renderer/src/lib/editor-themes/monokai.json new file mode 100644 index 00000000..3cdd3797 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/monokai.json @@ -0,0 +1,144 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "272822", + "token": "" + }, + { + "foreground": "75715e", + "token": "comment" + }, + { + "foreground": "e6db74", + "token": "string" + }, + { + "foreground": "ae81ff", + "token": "constant.numeric" + }, + { + "foreground": "ae81ff", + "token": "constant.language" + }, + { + "foreground": "ae81ff", + "token": "constant.character" + }, + { + "foreground": "ae81ff", + "token": "constant.other" + }, + { + "foreground": "f92672", + "token": "keyword" + }, + { + "foreground": "f92672", + "token": "storage" + }, + { + "foreground": "66d9ef", + "fontStyle": "italic", + "token": "storage.type" + }, + { + "foreground": "a6e22e", + "fontStyle": "underline", + "token": "entity.name.class" + }, + { + "foreground": "a6e22e", + "fontStyle": "italic underline", + "token": "entity.other.inherited-class" + }, + { + "foreground": "a6e22e", + "token": "entity.name.function" + }, + { + "foreground": "fd971f", + "fontStyle": "italic", + "token": "variable.parameter" + }, + { + "foreground": "f92672", + "token": "entity.name.tag" + }, + { + "foreground": "a6e22e", + "token": "entity.other.attribute-name" + }, + { + "foreground": "66d9ef", + "token": "support.function" + }, + { + "foreground": "66d9ef", + "token": "support.constant" + }, + { + "foreground": "66d9ef", + "fontStyle": "italic", + "token": "support.type" + }, + { + "foreground": "66d9ef", + "fontStyle": "italic", + "token": "support.class" + }, + { + "foreground": "f8f8f0", + "background": "f92672", + "token": "invalid" + }, + { + "foreground": "f8f8f0", + "background": "ae81ff", + "token": "invalid.deprecated" + }, + { + "foreground": "cfcfc2", + "token": "meta.structure.dictionary.json string.quoted.double.json" + }, + { + "foreground": "75715e", + "token": "meta.diff" + }, + { + "foreground": "75715e", + "token": "meta.diff.header" + }, + { + "foreground": "f92672", + "token": "markup.deleted" + }, + { + "foreground": "a6e22e", + "token": "markup.inserted" + }, + { + "foreground": "e6db74", + "token": "markup.changed" + }, + { + "foreground": "ae81ffa0", + "token": "constant.numeric.line-number.find-in-files - match" + }, + { + "foreground": "e6db74", + "token": "entity.name.filename.find-in-files" + } + ], + "colors": { + "editor.foreground": "#F8F8F2", + "editor.background": "#272822", + "editor.selectionBackground": "#49483E", + "editor.lineHighlightBackground": "#3E3D32", + "editorCursor.foreground": "#F8F8F0", + "editorWhitespace.foreground": "#3B3A32", + "editorIndentGuide.activeBackground": "#9D550FB0", + "editor.selectionHighlightBorder": "#222218" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/night-owl.json b/apps/desktop/src/renderer/src/lib/editor-themes/night-owl.json new file mode 100644 index 00000000..aae7b7d5 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/night-owl.json @@ -0,0 +1,680 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "011627", + "token": "" + }, + { + "foreground": "637777", + "token": "comment" + }, + { + "foreground": "addb67", + "token": "string" + }, + { + "foreground": "ecc48d", + "token": "vstring.quoted" + }, + { + "foreground": "ecc48d", + "token": "variable.other.readwrite.js" + }, + { + "foreground": "5ca7e4", + "token": "string.regexp" + }, + { + "foreground": "5ca7e4", + "token": "string.regexp keyword.other" + }, + { + "foreground": "5f7e97", + "token": "meta.function punctuation.separator.comma" + }, + { + "foreground": "f78c6c", + "token": "constant.numeric" + }, + { + "foreground": "f78c6c", + "token": "constant.character.numeric" + }, + { + "foreground": "addb67", + "token": "variable" + }, + { + "foreground": "c792ea", + "token": "keyword" + }, + { + "foreground": "c792ea", + "token": "punctuation.accessor" + }, + { + "foreground": "c792ea", + "token": "storage" + }, + { + "foreground": "c792ea", + "token": "meta.var.expr" + }, + { + "foreground": "c792ea", + "token": "meta.class meta.method.declaration meta.var.expr storage.type.jsm" + }, + { + "foreground": "c792ea", + "token": "storage.type.property.js" + }, + { + "foreground": "c792ea", + "token": "storage.type.property.ts" + }, + { + "foreground": "c792ea", + "token": "storage.type.property.tsx" + }, + { + "foreground": "82aaff", + "token": "storage.type" + }, + { + "foreground": "ffcb8b", + "token": "entity.name.class" + }, + { + "foreground": "ffcb8b", + "token": "meta.class entity.name.type.class" + }, + { + "foreground": "addb67", + "token": "entity.other.inherited-class" + }, + { + "foreground": "82aaff", + "token": "entity.name.function" + }, + { + "foreground": "addb67", + "token": "punctuation.definition.variable" + }, + { + "foreground": "d3423e", + "token": "punctuation.section.embedded" + }, + { + "foreground": "d6deeb", + "token": "punctuation.terminator.expression" + }, + { + "foreground": "d6deeb", + "token": "punctuation.definition.arguments" + }, + { + "foreground": "d6deeb", + "token": "punctuation.definition.array" + }, + { + "foreground": "d6deeb", + "token": "punctuation.section.array" + }, + { + "foreground": "d6deeb", + "token": "meta.array" + }, + { + "foreground": "d9f5dd", + "token": "punctuation.definition.list.begin" + }, + { + "foreground": "d9f5dd", + "token": "punctuation.definition.list.end" + }, + { + "foreground": "d9f5dd", + "token": "punctuation.separator.arguments" + }, + { + "foreground": "d9f5dd", + "token": "punctuation.definition.list" + }, + { + "foreground": "d3423e", + "token": "string.template meta.template.expression" + }, + { + "foreground": "d6deeb", + "token": "string.template punctuation.definition.string" + }, + { + "foreground": "c792ea", + "fontStyle": "italic", + "token": "italic" + }, + { + "foreground": "addb67", + "fontStyle": "bold", + "token": "bold" + }, + { + "foreground": "82aaff", + "token": "constant.language" + }, + { + "foreground": "82aaff", + "token": "punctuation.definition.constant" + }, + { + "foreground": "82aaff", + "token": "variable.other.constant" + }, + { + "foreground": "7fdbca", + "token": "support.function.construct" + }, + { + "foreground": "7fdbca", + "token": "keyword.other.new" + }, + { + "foreground": "82aaff", + "token": "constant.character" + }, + { + "foreground": "82aaff", + "token": "constant.other" + }, + { + "foreground": "f78c6c", + "token": "constant.character.escape" + }, + { + "foreground": "addb67", + "token": "entity.other.inherited-class" + }, + { + "foreground": "d7dbe0", + "token": "variable.parameter" + }, + { + "foreground": "7fdbca", + "token": "entity.name.tag" + }, + { + "foreground": "cc2996", + "token": "punctuation.definition.tag.html" + }, + { + "foreground": "cc2996", + "token": "punctuation.definition.tag.begin" + }, + { + "foreground": "cc2996", + "token": "punctuation.definition.tag.end" + }, + { + "foreground": "addb67", + "token": "entity.other.attribute-name" + }, + { + "foreground": "addb67", + "token": "entity.name.tag.custom" + }, + { + "foreground": "82aaff", + "token": "support.function" + }, + { + "foreground": "82aaff", + "token": "support.constant" + }, + { + "foreground": "7fdbca", + "token": "upport.constant.meta.property-value" + }, + { + "foreground": "addb67", + "token": "support.type" + }, + { + "foreground": "addb67", + "token": "support.class" + }, + { + "foreground": "addb67", + "token": "support.variable.dom" + }, + { + "foreground": "7fdbca", + "token": "support.constant" + }, + { + "foreground": "7fdbca", + "token": "keyword.other.special-method" + }, + { + "foreground": "7fdbca", + "token": "keyword.other.new" + }, + { + "foreground": "7fdbca", + "token": "keyword.other.debugger" + }, + { + "foreground": "7fdbca", + "token": "keyword.control" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.comparison" + }, + { + "foreground": "c792ea", + "token": "keyword.control.flow.js" + }, + { + "foreground": "c792ea", + "token": "keyword.control.flow.ts" + }, + { + "foreground": "c792ea", + "token": "keyword.control.flow.tsx" + }, + { + "foreground": "c792ea", + "token": "keyword.control.ruby" + }, + { + "foreground": "c792ea", + "token": "keyword.control.module.ruby" + }, + { + "foreground": "c792ea", + "token": "keyword.control.class.ruby" + }, + { + "foreground": "c792ea", + "token": "keyword.control.def.ruby" + }, + { + "foreground": "c792ea", + "token": "keyword.control.loop.js" + }, + { + "foreground": "c792ea", + "token": "keyword.control.loop.ts" + }, + { + "foreground": "c792ea", + "token": "keyword.control.import.js" + }, + { + "foreground": "c792ea", + "token": "keyword.control.import.ts" + }, + { + "foreground": "c792ea", + "token": "keyword.control.import.tsx" + }, + { + "foreground": "c792ea", + "token": "keyword.control.from.js" + }, + { + "foreground": "c792ea", + "token": "keyword.control.from.ts" + }, + { + "foreground": "c792ea", + "token": "keyword.control.from.tsx" + }, + { + "foreground": "ffffff", + "background": "ff2c83", + "token": "invalid" + }, + { + "foreground": "ffffff", + "background": "d3423e", + "token": "invalid.deprecated" + }, + { + "foreground": "7fdbca", + "token": "keyword.operator" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.relational" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.assignement" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.arithmetic" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.bitwise" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.increment" + }, + { + "foreground": "c792ea", + "token": "keyword.operator.ternary" + }, + { + "foreground": "637777", + "token": "comment.line.double-slash" + }, + { + "foreground": "cdebf7", + "token": "object" + }, + { + "foreground": "ff5874", + "token": "constant.language.null" + }, + { + "foreground": "d6deeb", + "token": "meta.brace" + }, + { + "foreground": "c792ea", + "token": "meta.delimiter.period" + }, + { + "foreground": "d9f5dd", + "token": "punctuation.definition.string" + }, + { + "foreground": "ff5874", + "token": "constant.language.boolean" + }, + { + "foreground": "ffffff", + "token": "object.comma" + }, + { + "foreground": "7fdbca", + "token": "variable.parameter.function" + }, + { + "foreground": "80cbc4", + "token": "support.type.vendor.property-name" + }, + { + "foreground": "80cbc4", + "token": "support.constant.vendor.property-value" + }, + { + "foreground": "80cbc4", + "token": "support.type.property-name" + }, + { + "foreground": "80cbc4", + "token": "meta.property-list entity.name.tag" + }, + { + "foreground": "57eaf1", + "token": "meta.property-list entity.name.tag.reference" + }, + { + "foreground": "f78c6c", + "token": "constant.other.color.rgb-value punctuation.definition.constant" + }, + { + "foreground": "ffeb95", + "token": "constant.other.color" + }, + { + "foreground": "ffeb95", + "token": "keyword.other.unit" + }, + { + "foreground": "c792ea", + "token": "meta.selector" + }, + { + "foreground": "fad430", + "token": "entity.other.attribute-name.id" + }, + { + "foreground": "80cbc4", + "token": "meta.property-name" + }, + { + "foreground": "c792ea", + "token": "entity.name.tag.doctype" + }, + { + "foreground": "c792ea", + "token": "meta.tag.sgml.doctype" + }, + { + "foreground": "d9f5dd", + "token": "punctuation.definition.parameters" + }, + { + "foreground": "ecc48d", + "token": "string.quoted" + }, + { + "foreground": "ecc48d", + "token": "string.quoted.double" + }, + { + "foreground": "ecc48d", + "token": "string.quoted.single" + }, + { + "foreground": "addb67", + "token": "support.constant.math" + }, + { + "foreground": "addb67", + "token": "support.type.property-name.json" + }, + { + "foreground": "addb67", + "token": "support.constant.json" + }, + { + "foreground": "c789d6", + "token": "meta.structure.dictionary.value.json string.quoted.double" + }, + { + "foreground": "80cbc4", + "token": "string.quoted.double.json punctuation.definition.string.json" + }, + { + "foreground": "ff5874", + "token": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language" + }, + { + "foreground": "d6deeb", + "token": "variable.other.ruby" + }, + { + "foreground": "ecc48d", + "token": "entity.name.type.class.ruby" + }, + { + "foreground": "ecc48d", + "token": "keyword.control.class.ruby" + }, + { + "foreground": "ecc48d", + "token": "meta.class.ruby" + }, + { + "foreground": "7fdbca", + "token": "constant.language.symbol.hashkey.ruby" + }, + { + "foreground": "e0eddd", + "background": "a57706", + "fontStyle": "italic", + "token": "meta.diff" + }, + { + "foreground": "e0eddd", + "background": "a57706", + "fontStyle": "italic", + "token": "meta.diff.header" + }, + { + "foreground": "ef535090", + "fontStyle": "italic", + "token": "markup.deleted" + }, + { + "foreground": "a2bffc", + "fontStyle": "italic", + "token": "markup.changed" + }, + { + "foreground": "a2bffc", + "fontStyle": "italic", + "token": "meta.diff.header.git" + }, + { + "foreground": "a2bffc", + "fontStyle": "italic", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "a2bffc", + "fontStyle": "italic", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "219186", + "background": "eae3ca", + "token": "markup.inserted" + }, + { + "foreground": "d3201f", + "token": "other.package.exclude" + }, + { + "foreground": "d3201f", + "token": "other.remove" + }, + { + "foreground": "269186", + "token": "other.add" + }, + { + "foreground": "ff5874", + "token": "constant.language.python" + }, + { + "foreground": "82aaff", + "token": "variable.parameter.function.python" + }, + { + "foreground": "82aaff", + "token": "meta.function-call.arguments.python" + }, + { + "foreground": "b2ccd6", + "token": "meta.function-call.python" + }, + { + "foreground": "b2ccd6", + "token": "meta.function-call.generic.python" + }, + { + "foreground": "d6deeb", + "token": "punctuation.python" + }, + { + "foreground": "addb67", + "token": "entity.name.function.decorator.python" + }, + { + "foreground": "8eace3", + "token": "source.python variable.language.special" + }, + { + "foreground": "82b1ff", + "token": "markup.heading.markdown" + }, + { + "foreground": "c792ea", + "fontStyle": "italic", + "token": "markup.italic.markdown" + }, + { + "foreground": "addb67", + "fontStyle": "bold", + "token": "markup.bold.markdown" + }, + { + "foreground": "697098", + "token": "markup.quote.markdown" + }, + { + "foreground": "80cbc4", + "token": "markup.inline.raw.markdown" + }, + { + "foreground": "ff869a", + "token": "markup.underline.link.markdown" + }, + { + "foreground": "ff869a", + "token": "markup.underline.link.image.markdown" + }, + { + "foreground": "d6deeb", + "token": "string.other.link.title.markdown" + }, + { + "foreground": "d6deeb", + "token": "string.other.link.description.markdown" + }, + { + "foreground": "82b1ff", + "token": "punctuation.definition.string.markdown" + }, + { + "foreground": "82b1ff", + "token": "punctuation.definition.string.begin.markdown" + }, + { + "foreground": "82b1ff", + "token": "punctuation.definition.string.end.markdown" + }, + { + "foreground": "82b1ff", + "token": "meta.link.inline.markdown punctuation.definition.string" + }, + { + "foreground": "7fdbca", + "token": "punctuation.definition.metadata.markdown" + }, + { + "foreground": "82b1ff", + "token": "beginning.punctuation.definition.list.markdown" + } + ], + "colors": { + "editor.foreground": "#d6deeb", + "editor.background": "#011627", + "editor.selectionBackground": "#5f7e9779", + "editor.lineHighlightBackground": "#010E17", + "editorCursor.foreground": "#80a4c2", + "editorWhitespace.foreground": "#2e2040", + "editorIndentGuide.background": "#5e81ce52", + "editor.selectionHighlightBorder": "#122d42" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/nord.json b/apps/desktop/src/renderer/src/lib/editor-themes/nord.json new file mode 100644 index 00000000..ea03bbb8 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/nord.json @@ -0,0 +1,93 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "2E3440", + "token": "" + }, + { + "foreground": "616e88", + "token": "comment" + }, + { + "foreground": "a3be8c", + "token": "string" + }, + { + "foreground": "b48ead", + "token": "constant.numeric" + }, + { + "foreground": "81a1c1", + "token": "constant.language" + }, + { + "foreground": "81a1c1", + "token": "keyword" + }, + { + "foreground": "81a1c1", + "token": "storage" + }, + { + "foreground": "81a1c1", + "token": "storage.type" + }, + { + "foreground": "8fbcbb", + "token": "entity.name.class" + }, + { + "foreground": "8fbcbb", + "fontStyle": " bold", + "token": "entity.other.inherited-class" + }, + { + "foreground": "88c0d0", + "token": "entity.name.function" + }, + { + "foreground": "81a1c1", + "token": "entity.name.tag" + }, + { + "foreground": "8fbcbb", + "token": "entity.other.attribute-name" + }, + { + "foreground": "88c0d0", + "token": "support.function" + }, + { + "foreground": "f8f8f0", + "background": "f92672", + "token": "invalid" + }, + { + "foreground": "f8f8f0", + "background": "ae81ff", + "token": "invalid.deprecated" + }, + { + "foreground": "b48ead", + "token": "constant.color.other.rgb-value" + }, + { + "foreground": "ebcb8b", + "token": "constant.character.escape" + }, + { + "foreground": "8fbcbb", + "token": "variable.other.constant" + } + ], + "colors": { + "editor.foreground": "#D8DEE9", + "editor.background": "#2E3440", + "editor.selectionBackground": "#434C5ECC", + "editor.lineHighlightBackground": "#3B4252", + "editorCursor.foreground": "#D8DEE9", + "editorWhitespace.foreground": "#434C5ECC" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/oceanic-next.json b/apps/desktop/src/renderer/src/lib/editor-themes/oceanic-next.json new file mode 100644 index 00000000..3fe23e27 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/oceanic-next.json @@ -0,0 +1,391 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "1B2B34", + "token": "" + }, + { + "foreground": "65737e", + "token": "comment" + }, + { + "foreground": "65737e", + "token": "punctuation.definition.comment" + }, + { + "foreground": "cdd3de", + "token": "variable" + }, + { + "foreground": "c594c5", + "token": "keyword" + }, + { + "foreground": "c594c5", + "token": "storage.type" + }, + { + "foreground": "c594c5", + "token": "storage.modifier" + }, + { + "foreground": "5fb3b3", + "token": "keyword.operator" + }, + { + "foreground": "5fb3b3", + "token": "constant.other.color" + }, + { + "foreground": "5fb3b3", + "token": "punctuation" + }, + { + "foreground": "5fb3b3", + "token": "meta.tag" + }, + { + "foreground": "5fb3b3", + "token": "punctuation.definition.tag" + }, + { + "foreground": "5fb3b3", + "token": "punctuation.separator.inheritance.php" + }, + { + "foreground": "5fb3b3", + "token": "punctuation.definition.tag.html" + }, + { + "foreground": "5fb3b3", + "token": "punctuation.definition.tag.begin.html" + }, + { + "foreground": "5fb3b3", + "token": "punctuation.definition.tag.end.html" + }, + { + "foreground": "5fb3b3", + "token": "punctuation.section.embedded" + }, + { + "foreground": "5fb3b3", + "token": "keyword.other.template" + }, + { + "foreground": "5fb3b3", + "token": "keyword.other.substitution" + }, + { + "foreground": "eb606b", + "token": "entity.name.tag" + }, + { + "foreground": "eb606b", + "token": "meta.tag.sgml" + }, + { + "foreground": "eb606b", + "token": "markup.deleted.git_gutter" + }, + { + "foreground": "6699cc", + "token": "entity.name.function" + }, + { + "foreground": "6699cc", + "token": "meta.function-call" + }, + { + "foreground": "6699cc", + "token": "variable.function" + }, + { + "foreground": "6699cc", + "token": "support.function" + }, + { + "foreground": "6699cc", + "token": "keyword.other.special-method" + }, + { + "foreground": "6699cc", + "token": "meta.block-level" + }, + { + "foreground": "f2777a", + "token": "support.other.variable" + }, + { + "foreground": "f2777a", + "token": "string.other.link" + }, + { + "foreground": "f99157", + "token": "constant.numeric" + }, + { + "foreground": "f99157", + "token": "constant.language" + }, + { + "foreground": "f99157", + "token": "support.constant" + }, + { + "foreground": "f99157", + "token": "constant.character" + }, + { + "foreground": "f99157", + "token": "variable.parameter" + }, + { + "foreground": "f99157", + "token": "keyword.other.unit" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "string" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "constant.other.symbol" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "constant.other.key" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "entity.other.inherited-class" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "markup.heading" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "markup.inserted.git_gutter" + }, + { + "foreground": "99c794", + "fontStyle": "normal", + "token": "meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js" + }, + { + "foreground": "fac863", + "token": "entity.name.class" + }, + { + "foreground": "fac863", + "token": "entity.name.type.class" + }, + { + "foreground": "fac863", + "token": "support.type" + }, + { + "foreground": "fac863", + "token": "support.class" + }, + { + "foreground": "fac863", + "token": "support.orther.namespace.use.php" + }, + { + "foreground": "fac863", + "token": "meta.use.php" + }, + { + "foreground": "fac863", + "token": "support.other.namespace.php" + }, + { + "foreground": "fac863", + "token": "markup.changed.git_gutter" + }, + { + "foreground": "ec5f67", + "token": "entity.name.module.js" + }, + { + "foreground": "ec5f67", + "token": "variable.import.parameter.js" + }, + { + "foreground": "ec5f67", + "token": "variable.other.class.js" + }, + { + "foreground": "ec5f67", + "fontStyle": "italic", + "token": "variable.language" + }, + { + "foreground": "cdd3de", + "token": "meta.group.braces.curly.js constant.other.object.key.js string.unquoted.label.js" + }, + { + "foreground": "d8dee9", + "token": "meta.class-method.js entity.name.function.js" + }, + { + "foreground": "d8dee9", + "token": "variable.function.constructor" + }, + { + "foreground": "d8dee9", + "token": "meta.class.js meta.class.property.js meta.method.js string.unquoted.js entity.name.function.js" + }, + { + "foreground": "bb80b3", + "token": "entity.other.attribute-name" + }, + { + "foreground": "99c794", + "token": "markup.inserted" + }, + { + "foreground": "ec5f67", + "token": "markup.deleted" + }, + { + "foreground": "bb80b3", + "token": "markup.changed" + }, + { + "foreground": "5fb3b3", + "token": "string.regexp" + }, + { + "foreground": "5fb3b3", + "token": "constant.character.escape" + }, + { + "fontStyle": "underline", + "token": "*url*" + }, + { + "fontStyle": "underline", + "token": "*link*" + }, + { + "fontStyle": "underline", + "token": "*uri*" + }, + { + "foreground": "ab7967", + "token": "constant.numeric.line-number.find-in-files - match" + }, + { + "foreground": "99c794", + "token": "entity.name.filename.find-in-files" + }, + { + "foreground": "6699cc", + "fontStyle": "italic", + "token": "tag.decorator.js entity.name.tag.js" + }, + { + "foreground": "6699cc", + "fontStyle": "italic", + "token": "tag.decorator.js punctuation.definition.tag.js" + }, + { + "foreground": "ec5f67", + "fontStyle": "italic", + "token": "source.js constant.other.object.key.js string.unquoted.label.js" + }, + { + "foreground": "fac863", + "token": "source.json meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "fac863", + "token": "source.json meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "c594c5", + "token": "source.json meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "c594c5", + "token": "source.json meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "d8dee9", + "token": "source.json meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "d8dee9", + "token": "source.json meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "6699cc", + "token": "source.json meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "6699cc", + "token": "source.json meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "ab7967", + "token": "source.json meta meta meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "ab7967", + "token": "source.json meta meta meta meta meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "ec5f67", + "token": "source.json meta meta meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "ec5f67", + "token": "source.json meta meta meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "f99157", + "token": "source.json meta meta meta meta.structure.dictionary.json string.quoted.double.json - meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "f99157", + "token": "source.json meta meta meta meta.structure.dictionary.json punctuation.definition.string - meta meta meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "fac863", + "token": "source.json meta meta.structure.dictionary.json string.quoted.double.json - meta meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "fac863", + "token": "source.json meta meta.structure.dictionary.json punctuation.definition.string - meta meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + }, + { + "foreground": "c594c5", + "token": "source.json meta.structure.dictionary.json string.quoted.double.json - meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json" + }, + { + "foreground": "c594c5", + "token": "source.json meta.structure.dictionary.json punctuation.definition.string - meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.definition.string" + } + ], + "colors": { + "editor.foreground": "#CDD3DE", + "editor.background": "#1B2B34", + "editor.selectionBackground": "#4f5b66", + "editor.lineHighlightBackground": "#65737e55", + "editorCursor.foreground": "#c0c5ce", + "editorWhitespace.foreground": "#65737e", + "editorIndentGuide.background": "#65737F", + "editorIndentGuide.activeBackground": "#FBC95A" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/solarized-dark.json b/apps/desktop/src/renderer/src/lib/editor-themes/solarized-dark.json new file mode 100644 index 00000000..404f3e25 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/solarized-dark.json @@ -0,0 +1,1086 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "002B36", + "token": "" + }, + { + "foreground": "586e75", + "token": "comment" + }, + { + "foreground": "2aa198", + "token": "string" + }, + { + "foreground": "586e75", + "token": "string" + }, + { + "foreground": "dc322f", + "token": "string.regexp" + }, + { + "foreground": "d33682", + "token": "constant.numeric" + }, + { + "foreground": "268bd2", + "token": "variable.language" + }, + { + "foreground": "268bd2", + "token": "variable.other" + }, + { + "foreground": "859900", + "token": "keyword" + }, + { + "foreground": "859900", + "token": "storage" + }, + { + "foreground": "268bd2", + "token": "entity.name.class" + }, + { + "foreground": "268bd2", + "token": "entity.name.type.class" + }, + { + "foreground": "268bd2", + "token": "entity.name.function" + }, + { + "foreground": "859900", + "token": "punctuation.definition.variable" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.embedded.begin" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.embedded.end" + }, + { + "foreground": "b58900", + "token": "constant.language" + }, + { + "foreground": "b58900", + "token": "meta.preprocessor" + }, + { + "foreground": "dc322f", + "token": "support.function.construct" + }, + { + "foreground": "dc322f", + "token": "keyword.other.new" + }, + { + "foreground": "cb4b16", + "token": "constant.character" + }, + { + "foreground": "cb4b16", + "token": "constant.other" + }, + { + "foreground": "268bd2", + "fontStyle": "bold", + "token": "entity.name.tag" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.tag.html" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.tag.begin" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.tag.end" + }, + { + "foreground": "93a1a1", + "token": "entity.other.attribute-name" + }, + { + "foreground": "268bd2", + "token": "support.function" + }, + { + "foreground": "dc322f", + "token": "punctuation.separator.continuation" + }, + { + "foreground": "859900", + "token": "support.type" + }, + { + "foreground": "859900", + "token": "support.class" + }, + { + "foreground": "cb4b16", + "token": "support.type.exception" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.special-method" + }, + { + "foreground": "2aa198", + "token": "string.quoted.double" + }, + { + "foreground": "2aa198", + "token": "string.quoted.single" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end" + }, + { + "foreground": "b58900", + "token": "entity.name.tag.css" + }, + { + "foreground": "b58900", + "token": "support.type.property-name.css" + }, + { + "foreground": "b58900", + "token": "meta.property-name.css" + }, + { + "foreground": "dc322f", + "token": "source.css" + }, + { + "foreground": "586e75", + "token": "meta.selector.css" + }, + { + "foreground": "6c71c4", + "token": "punctuation.section.property-list.css" + }, + { + "foreground": "2aa198", + "token": "meta.property-value.css constant.numeric.css" + }, + { + "foreground": "2aa198", + "token": "keyword.other.unit.css" + }, + { + "foreground": "2aa198", + "token": "constant.other.color.rgb-value.css" + }, + { + "foreground": "2aa198", + "token": "meta.property-value.css" + }, + { + "foreground": "dc322f", + "token": "keyword.other.important.css" + }, + { + "foreground": "2aa198", + "token": "support.constant.color" + }, + { + "foreground": "859900", + "token": "entity.name.tag.css" + }, + { + "foreground": "586e75", + "token": "punctuation.separator.key-value.css" + }, + { + "foreground": "586e75", + "token": "punctuation.terminator.rule.css" + }, + { + "foreground": "268bd2", + "token": "entity.other.attribute-name.class.css" + }, + { + "foreground": "cb4b16", + "token": "entity.other.attribute-name.pseudo-element.css" + }, + { + "foreground": "cb4b16", + "token": "entity.other.attribute-name.pseudo-class.css" + }, + { + "foreground": "268bd2", + "token": "entity.other.attribute-name.id.css" + }, + { + "foreground": "b58900", + "token": "meta.function.js" + }, + { + "foreground": "b58900", + "token": "entity.name.function.js" + }, + { + "foreground": "b58900", + "token": "support.function.dom.js" + }, + { + "foreground": "b58900", + "token": "text.html.basic source.js.embedded.html" + }, + { + "foreground": "268bd2", + "token": "storage.type.function.js" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.js" + }, + { + "foreground": "268bd2", + "token": "meta.brace.square.js" + }, + { + "foreground": "268bd2", + "token": "storage.type.js" + }, + { + "foreground": "93a1a1", + "token": "meta.brace.round" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.parameters.begin.js" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.parameters.end.js" + }, + { + "foreground": "268bd2", + "token": "meta.brace.curly.js" + }, + { + "foreground": "93a1a1", + "fontStyle": "italic", + "token": "entity.name.tag.doctype.html" + }, + { + "foreground": "93a1a1", + "fontStyle": "italic", + "token": "meta.tag.sgml.html" + }, + { + "foreground": "93a1a1", + "fontStyle": "italic", + "token": "string.quoted.double.doctype.identifiers-and-DTDs.html" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "comment.block.html" + }, + { + "fontStyle": "italic", + "token": "entity.name.tag.script.html" + }, + { + "foreground": "2aa198", + "token": "source.css.embedded.html string.quoted.double.html" + }, + { + "foreground": "cb4b16", + "fontStyle": "bold", + "token": "text.html.ruby" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.other.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.any.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.block.any" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.inline.any" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.structure.any.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic source.js.embedded.html" + }, + { + "foreground": "657b83", + "token": "punctuation.separator.key-value.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic entity.other.attribute-name.html" + }, + { + "foreground": "2aa198", + "token": "text.html.basic meta.tag.structure.any.html punctuation.definition.string.begin.html" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.begin.html" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.end.html" + }, + { + "foreground": "268bd2", + "fontStyle": "bold", + "token": "entity.name.tag.block.any.html" + }, + { + "fontStyle": "italic", + "token": "source.css.embedded.html entity.name.tag.style.html" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "source.css.embedded.html" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "comment.block.html" + }, + { + "foreground": "268bd2", + "token": "punctuation.definition.variable.ruby" + }, + { + "foreground": "657b83", + "token": "meta.function.method.with-arguments.ruby" + }, + { + "foreground": "2aa198", + "token": "variable.language.ruby" + }, + { + "foreground": "268bd2", + "token": "entity.name.function.ruby" + }, + { + "foreground": "859900", + "fontStyle": "bold", + "token": "keyword.control.ruby" + }, + { + "foreground": "859900", + "fontStyle": "bold", + "token": "keyword.control.def.ruby" + }, + { + "foreground": "859900", + "token": "keyword.control.class.ruby" + }, + { + "foreground": "859900", + "token": "meta.class.ruby" + }, + { + "foreground": "b58900", + "token": "entity.name.type.class.ruby" + }, + { + "foreground": "859900", + "token": "keyword.control.ruby" + }, + { + "foreground": "b58900", + "token": "support.class.ruby" + }, + { + "foreground": "859900", + "token": "keyword.other.special-method.ruby" + }, + { + "foreground": "2aa198", + "token": "constant.language.ruby" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.ruby" + }, + { + "foreground": "b58900", + "token": "variable.other.constant.ruby" + }, + { + "foreground": "2aa198", + "token": "constant.other.symbol.ruby" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.embedded.ruby" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin.ruby" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end.ruby" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.special-method.ruby" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.include.php" + }, + { + "foreground": "839496", + "token": "text.html.ruby meta.tag.inline.any.html" + }, + { + "foreground": "2aa198", + "token": "text.html.ruby punctuation.definition.string.begin" + }, + { + "foreground": "2aa198", + "token": "text.html.ruby punctuation.definition.string.end" + }, + { + "foreground": "839496", + "token": "punctuation.definition.string.begin" + }, + { + "foreground": "839496", + "token": "punctuation.definition.string.end" + }, + { + "foreground": "839496", + "token": "support.class.php" + }, + { + "foreground": "dc322f", + "token": "keyword.operator.index-start.php" + }, + { + "foreground": "dc322f", + "token": "keyword.operator.index-end.php" + }, + { + "foreground": "586e75", + "token": "meta.array.php" + }, + { + "foreground": "b58900", + "token": "meta.array.php support.function.construct.php" + }, + { + "foreground": "b58900", + "token": "meta.array.empty.php support.function.construct.php" + }, + { + "foreground": "b58900", + "token": "support.function.construct.php" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.array.begin" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.array.end" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.php" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.new.php" + }, + { + "foreground": "839496", + "token": "keyword.operator.class" + }, + { + "foreground": "93a1a1", + "token": "variable.other.property.php" + }, + { + "foreground": "b58900", + "token": "storage.modifier.extends.php" + }, + { + "foreground": "b58900", + "token": "storage.type.class.php" + }, + { + "foreground": "b58900", + "token": "keyword.operator.class.php" + }, + { + "foreground": "839496", + "token": "punctuation.terminator.expression.php" + }, + { + "foreground": "586e75", + "token": "meta.other.inherited-class.php" + }, + { + "foreground": "859900", + "token": "storage.type.php" + }, + { + "foreground": "93a1a1", + "token": "entity.name.function.php" + }, + { + "foreground": "859900", + "token": "support.function.construct.php" + }, + { + "foreground": "839496", + "token": "entity.name.type.class.php" + }, + { + "foreground": "839496", + "token": "meta.function-call.php" + }, + { + "foreground": "839496", + "token": "meta.function-call.static.php" + }, + { + "foreground": "839496", + "token": "meta.function-call.object.php" + }, + { + "foreground": "93a1a1", + "token": "keyword.other.phpdoc" + }, + { + "foreground": "cb4b16", + "token": "source.php.embedded.block.html" + }, + { + "foreground": "cb4b16", + "token": "storage.type.function.php" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.c" + }, + { + "foreground": "cb4b16", + "token": "meta.preprocessor.c.include" + }, + { + "foreground": "cb4b16", + "token": "meta.preprocessor.macro.c" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.define.c" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.include.c" + }, + { + "foreground": "cb4b16", + "token": "entity.name.function.preprocessor.c" + }, + { + "foreground": "2aa198", + "token": "meta.preprocessor.c.include string.quoted.other.lt-gt.include.c" + }, + { + "foreground": "2aa198", + "token": "meta.preprocessor.c.include punctuation.definition.string.begin.c" + }, + { + "foreground": "2aa198", + "token": "meta.preprocessor.c.include punctuation.definition.string.end.c" + }, + { + "foreground": "586e75", + "token": "support.function.C99.c" + }, + { + "foreground": "586e75", + "token": "support.function.any-method.c" + }, + { + "foreground": "586e75", + "token": "entity.name.function.c" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.begin.c" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.end.c" + }, + { + "foreground": "b58900", + "token": "storage.type.c" + }, + { + "foreground": "e0eddd", + "background": "b58900", + "fontStyle": "italic", + "token": "meta.diff" + }, + { + "foreground": "e0eddd", + "background": "b58900", + "fontStyle": "italic", + "token": "meta.diff.header" + }, + { + "foreground": "dc322f", + "background": "eee8d5", + "token": "markup.deleted" + }, + { + "foreground": "cb4b16", + "background": "eee8d5", + "token": "markup.changed" + }, + { + "foreground": "219186", + "background": "eee8d5", + "token": "markup.inserted" + }, + { + "foreground": "e0eddd", + "background": "b58900", + "token": "text.html.markdown meta.dummy.line-break" + }, + { + "foreground": "2aa198", + "token": "text.html.markdown markup.raw.inline" + }, + { + "foreground": "2aa198", + "token": "text.restructuredtext markup.raw" + }, + { + "foreground": "dc322f", + "token": "other.package.exclude" + }, + { + "foreground": "dc322f", + "token": "other.remove" + }, + { + "foreground": "2aa198", + "token": "other.add" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.group.tex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.arguments.begin.latex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.arguments.end.latex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.arguments.latex" + }, + { + "foreground": "b58900", + "token": "meta.group.braces.tex" + }, + { + "foreground": "b58900", + "token": "string.other.math.tex" + }, + { + "foreground": "cb4b16", + "token": "variable.parameter.function.latex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.constant.math.tex" + }, + { + "foreground": "2aa198", + "token": "text.tex.latex constant.other.math.tex" + }, + { + "foreground": "2aa198", + "token": "constant.other.general.math.tex" + }, + { + "foreground": "2aa198", + "token": "constant.other.general.math.tex" + }, + { + "foreground": "2aa198", + "token": "constant.character.math.tex" + }, + { + "foreground": "b58900", + "token": "string.other.math.tex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin.tex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end.tex" + }, + { + "foreground": "2aa198", + "token": "keyword.control.label.latex" + }, + { + "foreground": "2aa198", + "token": "text.tex.latex constant.other.general.math.tex" + }, + { + "foreground": "dc322f", + "token": "variable.parameter.definition.label.latex" + }, + { + "foreground": "859900", + "token": "support.function.be.latex" + }, + { + "foreground": "cb4b16", + "token": "support.function.section.latex" + }, + { + "foreground": "2aa198", + "token": "support.function.general.tex" + }, + { + "fontStyle": "italic", + "token": "punctuation.definition.comment.tex" + }, + { + "fontStyle": "italic", + "token": "comment.line.percentage.tex" + }, + { + "foreground": "2aa198", + "token": "keyword.control.ref.latex" + }, + { + "foreground": "586e75", + "token": "string.quoted.double.block.python" + }, + { + "foreground": "859900", + "token": "storage.type.class.python" + }, + { + "foreground": "859900", + "token": "storage.type.function.python" + }, + { + "foreground": "859900", + "token": "storage.modifier.global.python" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.python" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.from.python" + }, + { + "foreground": "b58900", + "token": "support.type.exception.python" + }, + { + "foreground": "859900", + "token": "support.function.builtin.shell" + }, + { + "foreground": "cb4b16", + "token": "variable.other.normal.shell" + }, + { + "foreground": "268bd2", + "token": "source.shell" + }, + { + "foreground": "586e75", + "token": "meta.scope.for-in-loop.shell" + }, + { + "foreground": "586e75", + "token": "variable.other.loop.shell" + }, + { + "foreground": "859900", + "token": "punctuation.definition.string.end.shell" + }, + { + "foreground": "859900", + "token": "punctuation.definition.string.begin.shell" + }, + { + "foreground": "586e75", + "token": "meta.scope.case-block.shell" + }, + { + "foreground": "586e75", + "token": "meta.scope.case-body.shell" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.logical-expression.shell" + }, + { + "fontStyle": "italic", + "token": "comment.line.number-sign.shell" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.import.java" + }, + { + "foreground": "586e75", + "token": "storage.modifier.import.java" + }, + { + "foreground": "b58900", + "token": "meta.class.java storage.modifier.java" + }, + { + "foreground": "586e75", + "token": "source.java comment.block" + }, + { + "foreground": "586e75", + "token": "comment.block meta.documentation.tag.param.javadoc keyword.other.documentation.param.javadoc" + }, + { + "foreground": "b58900", + "token": "punctuation.definition.variable.perl" + }, + { + "foreground": "b58900", + "token": "variable.other.readwrite.global.perl" + }, + { + "foreground": "b58900", + "token": "variable.other.predefined.perl" + }, + { + "foreground": "b58900", + "token": "keyword.operator.comparison.perl" + }, + { + "foreground": "859900", + "token": "support.function.perl" + }, + { + "foreground": "586e75", + "fontStyle": "italic", + "token": "comment.line.number-sign.perl" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.begin.perl" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.end.perl" + }, + { + "foreground": "dc322f", + "token": "constant.character.escape.perl" + }, + { + "foreground": "268bd2", + "token": "markup.heading.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.1.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.2.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.3.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.4.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.5.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.6.markdown" + }, + { + "foreground": "839496", + "fontStyle": "bold", + "token": "markup.bold.markdown" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "markup.italic.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.bold.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.italic.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.raw.markdown" + }, + { + "foreground": "b58900", + "token": "markup.list.unnumbered.markdown" + }, + { + "foreground": "859900", + "token": "markup.list.numbered.markdown" + }, + { + "foreground": "2aa198", + "token": "markup.raw.block.markdown" + }, + { + "foreground": "2aa198", + "token": "markup.raw.inline.markdown" + }, + { + "foreground": "6c71c4", + "token": "markup.quote.markdown" + }, + { + "foreground": "6c71c4", + "token": "punctuation.definition.blockquote.markdown" + }, + { + "foreground": "d33682", + "token": "meta.separator.markdown" + }, + { + "foreground": "586e75", + "fontStyle": "italic", + "token": "meta.image.inline.markdown" + }, + { + "foreground": "586e75", + "fontStyle": "italic", + "token": "markup.underline.link.markdown" + }, + { + "foreground": "93a1a1", + "token": "string.other.link.title.markdown" + }, + { + "foreground": "93a1a1", + "token": "string.other.link.description.markdown" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.link.markdown" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.metadata.markdown" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.string.begin.markdown" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.string.end.markdown" + }, + { + "foreground": "586e75", + "token": "punctuation.definition.constant.markdown" + }, + { + "foreground": "eee8d5", + "background": "eee8d5", + "token": "sublimelinter.notes" + }, + { + "foreground": "93a1a1", + "background": "93a1a1", + "token": "sublimelinter.outline.illegal" + }, + { + "background": "dc322f", + "token": "sublimelinter.underline.illegal" + }, + { + "foreground": "839496", + "background": "839496", + "token": "sublimelinter.outline.warning" + }, + { + "background": "b58900", + "token": "sublimelinter.underline.warning" + }, + { + "foreground": "657b83", + "background": "657b83", + "token": "sublimelinter.outline.violation" + }, + { + "background": "cb4b16", + "token": "sublimelinter.underline.violation" + } + ], + "colors": { + "editor.foreground": "#839496", + "editor.background": "#002B36", + "editor.selectionBackground": "#073642", + "editor.lineHighlightBackground": "#073642", + "editorCursor.foreground": "#819090", + "editorWhitespace.foreground": "#073642" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/solarized-light.json b/apps/desktop/src/renderer/src/lib/editor-themes/solarized-light.json new file mode 100644 index 00000000..f32b9855 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/solarized-light.json @@ -0,0 +1,1077 @@ +{ + "base": "vs", + "inherit": true, + "rules": [ + { + "background": "FDF6E3", + "token": "" + }, + { + "foreground": "93a1a1", + "token": "comment" + }, + { + "foreground": "2aa198", + "token": "string" + }, + { + "foreground": "586e75", + "token": "string" + }, + { + "foreground": "dc322f", + "token": "string.regexp" + }, + { + "foreground": "d33682", + "token": "constant.numeric" + }, + { + "foreground": "268bd2", + "token": "variable.language" + }, + { + "foreground": "268bd2", + "token": "variable.other" + }, + { + "foreground": "859900", + "token": "keyword" + }, + { + "foreground": "073642", + "fontStyle": "bold", + "token": "storage" + }, + { + "foreground": "268bd2", + "token": "entity.name.class" + }, + { + "foreground": "268bd2", + "token": "entity.name.type.class" + }, + { + "foreground": "268bd2", + "token": "entity.name.function" + }, + { + "foreground": "859900", + "token": "punctuation.definition.variable" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.embedded.begin" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.embedded.end" + }, + { + "foreground": "b58900", + "token": "constant.language" + }, + { + "foreground": "b58900", + "token": "meta.preprocessor" + }, + { + "foreground": "dc322f", + "token": "support.function.construct" + }, + { + "foreground": "dc322f", + "token": "keyword.other.new" + }, + { + "foreground": "cb4b16", + "token": "constant.character" + }, + { + "foreground": "cb4b16", + "token": "constant.other" + }, + { + "foreground": "268bd2", + "fontStyle": "bold", + "token": "entity.name.tag" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.tag.html" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.tag.begin" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.tag.end" + }, + { + "foreground": "93a1a1", + "token": "entity.other.attribute-name" + }, + { + "foreground": "268bd2", + "token": "support.function" + }, + { + "foreground": "dc322f", + "token": "punctuation.separator.continuation" + }, + { + "foreground": "859900", + "token": "support.type" + }, + { + "foreground": "859900", + "token": "support.class" + }, + { + "foreground": "cb4b16", + "token": "support.type.exception" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.special-method" + }, + { + "foreground": "2aa198", + "token": "string.quoted.double" + }, + { + "foreground": "2aa198", + "token": "string.quoted.single" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end" + }, + { + "foreground": "b58900", + "token": "entity.name.tag.css" + }, + { + "foreground": "b58900", + "token": "support.type.property-name.css" + }, + { + "foreground": "b58900", + "token": "meta.property-name.css" + }, + { + "foreground": "dc322f", + "token": "source.css" + }, + { + "foreground": "586e75", + "token": "meta.selector.css" + }, + { + "foreground": "6c71c4", + "token": "punctuation.section.property-list.css" + }, + { + "foreground": "2aa198", + "token": "meta.property-value.css constant.numeric.css" + }, + { + "foreground": "2aa198", + "token": "keyword.other.unit.css" + }, + { + "foreground": "2aa198", + "token": "constant.other.color.rgb-value.css" + }, + { + "foreground": "2aa198", + "token": "meta.property-value.css" + }, + { + "foreground": "dc322f", + "token": "keyword.other.important.css" + }, + { + "foreground": "2aa198", + "token": "support.constant.color" + }, + { + "foreground": "859900", + "token": "entity.name.tag.css" + }, + { + "foreground": "586e75", + "token": "punctuation.separator.key-value.css" + }, + { + "foreground": "586e75", + "token": "punctuation.terminator.rule.css" + }, + { + "foreground": "268bd2", + "token": "entity.other.attribute-name.class.css" + }, + { + "foreground": "cb4b16", + "token": "entity.other.attribute-name.pseudo-element.css" + }, + { + "foreground": "cb4b16", + "token": "entity.other.attribute-name.pseudo-class.css" + }, + { + "foreground": "268bd2", + "token": "entity.other.attribute-name.id.css" + }, + { + "foreground": "b58900", + "token": "meta.function.js" + }, + { + "foreground": "b58900", + "token": "entity.name.function.js" + }, + { + "foreground": "b58900", + "token": "support.function.dom.js" + }, + { + "foreground": "b58900", + "token": "text.html.basic source.js.embedded.html" + }, + { + "foreground": "268bd2", + "token": "storage.type.function.js" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.js" + }, + { + "foreground": "268bd2", + "token": "meta.brace.square.js" + }, + { + "foreground": "268bd2", + "token": "storage.type.js" + }, + { + "foreground": "93a1a1", + "token": "meta.brace.round" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.parameters.begin.js" + }, + { + "foreground": "93a1a1", + "token": "punctuation.definition.parameters.end.js" + }, + { + "foreground": "268bd2", + "token": "meta.brace.curly.js" + }, + { + "foreground": "93a1a1", + "fontStyle": "italic", + "token": "entity.name.tag.doctype.html" + }, + { + "foreground": "93a1a1", + "fontStyle": "italic", + "token": "meta.tag.sgml.html" + }, + { + "foreground": "93a1a1", + "fontStyle": "italic", + "token": "string.quoted.double.doctype.identifiers-and-DTDs.html" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "comment.block.html" + }, + { + "fontStyle": "italic", + "token": "entity.name.tag.script.html" + }, + { + "foreground": "2aa198", + "token": "source.css.embedded.html string.quoted.double.html" + }, + { + "foreground": "cb4b16", + "fontStyle": "bold", + "token": "text.html.ruby" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.other.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.any.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.block.any" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.inline.any" + }, + { + "foreground": "657b83", + "token": "text.html.basic meta.tag.structure.any.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic source.js.embedded.html" + }, + { + "foreground": "657b83", + "token": "punctuation.separator.key-value.html" + }, + { + "foreground": "657b83", + "token": "text.html.basic entity.other.attribute-name.html" + }, + { + "foreground": "2aa198", + "token": "text.html.basic meta.tag.structure.any.html punctuation.definition.string.begin.html" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.begin.html" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.end.html" + }, + { + "foreground": "268bd2", + "fontStyle": "bold", + "token": "entity.name.tag.block.any.html" + }, + { + "fontStyle": "italic", + "token": "source.css.embedded.html entity.name.tag.style.html" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "source.css.embedded.html" + }, + { + "foreground": "839496", + "fontStyle": "italic", + "token": "comment.block.html" + }, + { + "foreground": "268bd2", + "token": "punctuation.definition.variable.ruby" + }, + { + "foreground": "657b83", + "token": "meta.function.method.with-arguments.ruby" + }, + { + "foreground": "2aa198", + "token": "variable.language.ruby" + }, + { + "foreground": "268bd2", + "token": "entity.name.function.ruby" + }, + { + "foreground": "859900", + "fontStyle": "bold", + "token": "keyword.control.ruby" + }, + { + "foreground": "859900", + "fontStyle": "bold", + "token": "keyword.control.def.ruby" + }, + { + "foreground": "859900", + "token": "keyword.control.class.ruby" + }, + { + "foreground": "859900", + "token": "meta.class.ruby" + }, + { + "foreground": "b58900", + "token": "entity.name.type.class.ruby" + }, + { + "foreground": "859900", + "token": "keyword.control.ruby" + }, + { + "foreground": "b58900", + "token": "support.class.ruby" + }, + { + "foreground": "859900", + "token": "keyword.other.special-method.ruby" + }, + { + "foreground": "2aa198", + "token": "constant.language.ruby" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.ruby" + }, + { + "foreground": "b58900", + "token": "variable.other.constant.ruby" + }, + { + "foreground": "2aa198", + "token": "constant.other.symbol.ruby" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.embedded.ruby" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin.ruby" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end.ruby" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.special-method.ruby" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.include.php" + }, + { + "foreground": "839496", + "token": "text.html.ruby meta.tag.inline.any.html" + }, + { + "foreground": "2aa198", + "token": "text.html.ruby punctuation.definition.string.begin" + }, + { + "foreground": "2aa198", + "token": "text.html.ruby punctuation.definition.string.end" + }, + { + "foreground": "839496", + "token": "punctuation.definition.string.begin" + }, + { + "foreground": "839496", + "token": "punctuation.definition.string.end" + }, + { + "foreground": "dc322f", + "token": "keyword.operator.index-start.php" + }, + { + "foreground": "dc322f", + "token": "keyword.operator.index-end.php" + }, + { + "foreground": "586e75", + "token": "meta.array.php" + }, + { + "foreground": "b58900", + "token": "meta.array.php support.function.construct.php" + }, + { + "foreground": "b58900", + "token": "meta.array.empty.php support.function.construct.php" + }, + { + "foreground": "b58900", + "token": "support.function.construct.php" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.array.begin" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.array.end" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.php" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.new.php" + }, + { + "foreground": "586e75", + "token": "support.class.php" + }, + { + "foreground": "586e75", + "token": "keyword.operator.class" + }, + { + "foreground": "93a1a1", + "token": "variable.other.property.php" + }, + { + "foreground": "b58900", + "token": "storage.modifier.extends.php" + }, + { + "foreground": "b58900", + "token": "storage.type.class.php" + }, + { + "foreground": "b58900", + "token": "keyword.operator.class.php" + }, + { + "foreground": "586e75", + "token": "meta.other.inherited-class.php" + }, + { + "foreground": "859900", + "token": "storage.type.php" + }, + { + "foreground": "93a1a1", + "token": "entity.name.function.php" + }, + { + "foreground": "859900", + "token": "support.function.construct.php" + }, + { + "foreground": "839496", + "token": "entity.name.type.class.php" + }, + { + "foreground": "839496", + "token": "meta.function-call.php" + }, + { + "foreground": "839496", + "token": "meta.function-call.static.php" + }, + { + "foreground": "839496", + "token": "meta.function-call.object.php" + }, + { + "foreground": "93a1a1", + "token": "keyword.other.phpdoc" + }, + { + "foreground": "cb4b16", + "token": "source.php.embedded.block.html" + }, + { + "foreground": "cb4b16", + "token": "storage.type.function.php" + }, + { + "foreground": "2aa198", + "token": "constant.numeric.c" + }, + { + "foreground": "cb4b16", + "token": "meta.preprocessor.c.include" + }, + { + "foreground": "cb4b16", + "token": "meta.preprocessor.macro.c" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.define.c" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.include.c" + }, + { + "foreground": "cb4b16", + "token": "entity.name.function.preprocessor.c" + }, + { + "foreground": "2aa198", + "token": "meta.preprocessor.c.include string.quoted.other.lt-gt.include.c" + }, + { + "foreground": "2aa198", + "token": "meta.preprocessor.c.include punctuation.definition.string.begin.c" + }, + { + "foreground": "2aa198", + "token": "meta.preprocessor.c.include punctuation.definition.string.end.c" + }, + { + "foreground": "586e75", + "token": "support.function.C99.c" + }, + { + "foreground": "586e75", + "token": "support.function.any-method.c" + }, + { + "foreground": "586e75", + "token": "entity.name.function.c" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.begin.c" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.end.c" + }, + { + "foreground": "b58900", + "token": "storage.type.c" + }, + { + "foreground": "e0eddd", + "background": "b58900", + "fontStyle": "italic", + "token": "meta.diff" + }, + { + "foreground": "e0eddd", + "background": "b58900", + "fontStyle": "italic", + "token": "meta.diff.header" + }, + { + "foreground": "dc322f", + "background": "eee8d5", + "token": "markup.deleted" + }, + { + "foreground": "cb4b16", + "background": "eee8d5", + "token": "markup.changed" + }, + { + "foreground": "219186", + "background": "eee8d5", + "token": "markup.inserted" + }, + { + "foreground": "e0eddd", + "background": "a57706", + "token": "text.html.markdown meta.dummy.line-break" + }, + { + "foreground": "2aa198", + "token": "text.html.markdown markup.raw.inline" + }, + { + "foreground": "2aa198", + "token": "text.restructuredtext markup.raw" + }, + { + "foreground": "dc322f", + "token": "other.package.exclude" + }, + { + "foreground": "dc322f", + "token": "other.remove" + }, + { + "foreground": "2aa198", + "token": "other.add" + }, + { + "foreground": "dc322f", + "token": "punctuation.section.group.tex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.arguments.begin.latex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.arguments.end.latex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.arguments.latex" + }, + { + "foreground": "b58900", + "token": "meta.group.braces.tex" + }, + { + "foreground": "b58900", + "token": "string.other.math.tex" + }, + { + "foreground": "cb4b16", + "token": "variable.parameter.function.latex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.constant.math.tex" + }, + { + "foreground": "2aa198", + "token": "text.tex.latex constant.other.math.tex" + }, + { + "foreground": "2aa198", + "token": "constant.other.general.math.tex" + }, + { + "foreground": "2aa198", + "token": "constant.other.general.math.tex" + }, + { + "foreground": "2aa198", + "token": "constant.character.math.tex" + }, + { + "foreground": "b58900", + "token": "string.other.math.tex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin.tex" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end.tex" + }, + { + "foreground": "2aa198", + "token": "keyword.control.label.latex" + }, + { + "foreground": "2aa198", + "token": "text.tex.latex constant.other.general.math.tex" + }, + { + "foreground": "dc322f", + "token": "variable.parameter.definition.label.latex" + }, + { + "foreground": "859900", + "token": "support.function.be.latex" + }, + { + "foreground": "cb4b16", + "token": "support.function.section.latex" + }, + { + "foreground": "2aa198", + "token": "support.function.general.tex" + }, + { + "fontStyle": "italic", + "token": "punctuation.definition.comment.tex" + }, + { + "fontStyle": "italic", + "token": "comment.line.percentage.tex" + }, + { + "foreground": "2aa198", + "token": "keyword.control.ref.latex" + }, + { + "foreground": "586e75", + "token": "string.quoted.double.block.python" + }, + { + "foreground": "859900", + "token": "storage.type.class.python" + }, + { + "foreground": "859900", + "token": "storage.type.function.python" + }, + { + "foreground": "859900", + "token": "storage.modifier.global.python" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.python" + }, + { + "foreground": "cb4b16", + "token": "keyword.control.import.from.python" + }, + { + "foreground": "b58900", + "token": "support.type.exception.python" + }, + { + "foreground": "859900", + "token": "support.function.builtin.shell" + }, + { + "foreground": "cb4b16", + "token": "variable.other.normal.shell" + }, + { + "foreground": "268bd2", + "token": "source.shell" + }, + { + "foreground": "586e75", + "token": "meta.scope.for-in-loop.shell" + }, + { + "foreground": "586e75", + "token": "variable.other.loop.shell" + }, + { + "foreground": "859900", + "token": "punctuation.definition.string.end.shell" + }, + { + "foreground": "859900", + "token": "punctuation.definition.string.begin.shell" + }, + { + "foreground": "586e75", + "token": "meta.scope.case-block.shell" + }, + { + "foreground": "586e75", + "token": "meta.scope.case-body.shell" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.logical-expression.shell" + }, + { + "fontStyle": "italic", + "token": "comment.line.number-sign.shell" + }, + { + "foreground": "cb4b16", + "token": "keyword.other.import.java" + }, + { + "foreground": "586e75", + "token": "storage.modifier.import.java" + }, + { + "foreground": "b58900", + "token": "meta.class.java storage.modifier.java" + }, + { + "foreground": "586e75", + "token": "source.java comment.block" + }, + { + "foreground": "586e75", + "token": "comment.block meta.documentation.tag.param.javadoc keyword.other.documentation.param.javadoc" + }, + { + "foreground": "b58900", + "token": "punctuation.definition.variable.perl" + }, + { + "foreground": "b58900", + "token": "variable.other.readwrite.global.perl" + }, + { + "foreground": "b58900", + "token": "variable.other.predefined.perl" + }, + { + "foreground": "b58900", + "token": "keyword.operator.comparison.perl" + }, + { + "foreground": "859900", + "token": "support.function.perl" + }, + { + "foreground": "586e75", + "fontStyle": "italic", + "token": "comment.line.number-sign.perl" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.begin.perl" + }, + { + "foreground": "2aa198", + "token": "punctuation.definition.string.end.perl" + }, + { + "foreground": "dc322f", + "token": "constant.character.escape.perl" + }, + { + "foreground": "268bd2", + "token": "markup.heading.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.1.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.2.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.3.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.4.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.5.markdown" + }, + { + "foreground": "268bd2", + "token": "markup.heading.6.markdown" + }, + { + "foreground": "586e75", + "fontStyle": "bold", + "token": "markup.bold.markdown" + }, + { + "foreground": "586e75", + "fontStyle": "italic", + "token": "markup.italic.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.bold.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.italic.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.raw.markdown" + }, + { + "foreground": "b58900", + "token": "markup.list.unnumbered.markdown" + }, + { + "foreground": "859900", + "token": "markup.list.numbered.markdown" + }, + { + "foreground": "2aa198", + "token": "markup.raw.block.markdown" + }, + { + "foreground": "2aa198", + "token": "markup.raw.inline.markdown" + }, + { + "foreground": "6c71c4", + "token": "markup.quote.markdown" + }, + { + "foreground": "6c71c4", + "token": "punctuation.definition.blockquote.markdown" + }, + { + "foreground": "d33682", + "token": "meta.separator.markdown" + }, + { + "foreground": "839496", + "token": "markup.underline.link.markdown" + }, + { + "foreground": "839496", + "token": "markup.underline.link.markdown" + }, + { + "foreground": "dc322f", + "token": "meta.link.inet.markdown" + }, + { + "foreground": "dc322f", + "token": "meta.link.email.lt-gt.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.begin.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.string.end.markdown" + }, + { + "foreground": "dc322f", + "token": "punctuation.definition.link.markdown" + }, + { + "foreground": "6a8187", + "token": "text.plain" + }, + { + "foreground": "eee8d5", + "background": "eee8d5", + "token": "sublimelinter.notes" + }, + { + "foreground": "93a1a1", + "background": "93a1a1", + "token": "sublimelinter.outline.illegal" + }, + { + "background": "dc322f", + "token": "sublimelinter.underline.illegal" + }, + { + "foreground": "839496", + "background": "839496", + "token": "sublimelinter.outline.warning" + }, + { + "background": "b58900", + "token": "sublimelinter.underline.warning" + }, + { + "foreground": "657b83", + "background": "657b83", + "token": "sublimelinter.outline.violation" + }, + { + "background": "cb4b16", + "token": "sublimelinter.underline.violation" + } + ], + "colors": { + "editor.foreground": "#586E75", + "editor.background": "#FDF6E3", + "editor.selectionBackground": "#EEE8D5", + "editor.lineHighlightBackground": "#EEE8D5", + "editorCursor.foreground": "#000000", + "editorWhitespace.foreground": "#EAE3C9" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/tomorrow-night.json b/apps/desktop/src/renderer/src/lib/editor-themes/tomorrow-night.json new file mode 100644 index 00000000..04a83d63 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/tomorrow-night.json @@ -0,0 +1,244 @@ +{ + "base": "vs-dark", + "inherit": true, + "rules": [ + { + "background": "1D1F21", + "token": "" + }, + { + "foreground": "969896", + "token": "comment" + }, + { + "foreground": "ced1cf", + "token": "keyword.operator.class" + }, + { + "foreground": "ced1cf", + "token": "constant.other" + }, + { + "foreground": "ced1cf", + "token": "source.php.embedded.line" + }, + { + "foreground": "cc6666", + "token": "variable" + }, + { + "foreground": "cc6666", + "token": "support.other.variable" + }, + { + "foreground": "cc6666", + "token": "string.other.link" + }, + { + "foreground": "cc6666", + "token": "string.regexp" + }, + { + "foreground": "cc6666", + "token": "entity.name.tag" + }, + { + "foreground": "cc6666", + "token": "entity.other.attribute-name" + }, + { + "foreground": "cc6666", + "token": "meta.tag" + }, + { + "foreground": "cc6666", + "token": "declaration.tag" + }, + { + "foreground": "cc6666", + "token": "markup.deleted.git_gutter" + }, + { + "foreground": "de935f", + "token": "constant.numeric" + }, + { + "foreground": "de935f", + "token": "constant.language" + }, + { + "foreground": "de935f", + "token": "support.constant" + }, + { + "foreground": "de935f", + "token": "constant.character" + }, + { + "foreground": "de935f", + "token": "variable.parameter" + }, + { + "foreground": "de935f", + "token": "punctuation.section.embedded" + }, + { + "foreground": "de935f", + "token": "keyword.other.unit" + }, + { + "foreground": "f0c674", + "token": "entity.name.class" + }, + { + "foreground": "f0c674", + "token": "entity.name.type.class" + }, + { + "foreground": "f0c674", + "token": "support.type" + }, + { + "foreground": "f0c674", + "token": "support.class" + }, + { + "foreground": "b5bd68", + "token": "string" + }, + { + "foreground": "b5bd68", + "token": "constant.other.symbol" + }, + { + "foreground": "b5bd68", + "token": "entity.other.inherited-class" + }, + { + "foreground": "b5bd68", + "token": "markup.heading" + }, + { + "foreground": "b5bd68", + "token": "markup.inserted.git_gutter" + }, + { + "foreground": "8abeb7", + "token": "keyword.operator" + }, + { + "foreground": "8abeb7", + "token": "constant.other.color" + }, + { + "foreground": "81a2be", + "token": "entity.name.function" + }, + { + "foreground": "81a2be", + "token": "meta.function-call" + }, + { + "foreground": "81a2be", + "token": "support.function" + }, + { + "foreground": "81a2be", + "token": "keyword.other.special-method" + }, + { + "foreground": "81a2be", + "token": "meta.block-level" + }, + { + "foreground": "81a2be", + "token": "markup.changed.git_gutter" + }, + { + "foreground": "b294bb", + "token": "keyword" + }, + { + "foreground": "b294bb", + "token": "storage" + }, + { + "foreground": "b294bb", + "token": "storage.type" + }, + { + "foreground": "b294bb", + "token": "entity.name.tag.css" + }, + { + "foreground": "ced2cf", + "background": "df5f5f", + "token": "invalid" + }, + { + "foreground": "ced2cf", + "background": "82a3bf", + "token": "meta.separator" + }, + { + "foreground": "ced2cf", + "background": "b798bf", + "token": "invalid.deprecated" + }, + { + "foreground": "ffffff", + "token": "markup.inserted.diff" + }, + { + "foreground": "ffffff", + "token": "markup.deleted.diff" + }, + { + "foreground": "ffffff", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "ffffff", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "718c00", + "token": "markup.inserted.diff" + }, + { + "foreground": "718c00", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "c82829", + "token": "markup.deleted.diff" + }, + { + "foreground": "c82829", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "3e999f", + "fontStyle": "italic", + "token": "meta.diff.range" + } + ], + "colors": { + "editor.foreground": "#C5C8C6", + "editor.background": "#1D1F21", + "editor.selectionBackground": "#373B41", + "editor.lineHighlightBackground": "#282A2E", + "editorCursor.foreground": "#AEAFAD", + "editorWhitespace.foreground": "#4B4E55" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/editor-themes/tomorrow.json b/apps/desktop/src/renderer/src/lib/editor-themes/tomorrow.json new file mode 100644 index 00000000..fbeac222 --- /dev/null +++ b/apps/desktop/src/renderer/src/lib/editor-themes/tomorrow.json @@ -0,0 +1,240 @@ +{ + "base": "vs", + "inherit": true, + "rules": [ + { + "background": "FFFFFF", + "token": "" + }, + { + "foreground": "8e908c", + "token": "comment" + }, + { + "foreground": "666969", + "token": "keyword.operator.class" + }, + { + "foreground": "666969", + "token": "constant.other" + }, + { + "foreground": "666969", + "token": "source.php.embedded.line" + }, + { + "foreground": "c82829", + "token": "variable" + }, + { + "foreground": "c82829", + "token": "support.other.variable" + }, + { + "foreground": "c82829", + "token": "string.other.link" + }, + { + "foreground": "c82829", + "token": "string.regexp" + }, + { + "foreground": "c82829", + "token": "entity.name.tag" + }, + { + "foreground": "c82829", + "token": "entity.other.attribute-name" + }, + { + "foreground": "c82829", + "token": "meta.tag" + }, + { + "foreground": "c82829", + "token": "declaration.tag" + }, + { + "foreground": "c82829", + "token": "markup.deleted.git_gutter" + }, + { + "foreground": "f5871f", + "token": "constant.numeric" + }, + { + "foreground": "f5871f", + "token": "constant.language" + }, + { + "foreground": "f5871f", + "token": "support.constant" + }, + { + "foreground": "f5871f", + "token": "constant.character" + }, + { + "foreground": "f5871f", + "token": "variable.parameter" + }, + { + "foreground": "f5871f", + "token": "punctuation.section.embedded" + }, + { + "foreground": "f5871f", + "token": "keyword.other.unit" + }, + { + "foreground": "c99e00", + "token": "entity.name.class" + }, + { + "foreground": "c99e00", + "token": "entity.name.type.class" + }, + { + "foreground": "c99e00", + "token": "support.type" + }, + { + "foreground": "c99e00", + "token": "support.class" + }, + { + "foreground": "718c00", + "token": "string" + }, + { + "foreground": "718c00", + "token": "constant.other.symbol" + }, + { + "foreground": "718c00", + "token": "entity.other.inherited-class" + }, + { + "foreground": "718c00", + "token": "markup.heading" + }, + { + "foreground": "718c00", + "token": "markup.inserted.git_gutter" + }, + { + "foreground": "3e999f", + "token": "keyword.operator" + }, + { + "foreground": "3e999f", + "token": "constant.other.color" + }, + { + "foreground": "4271ae", + "token": "entity.name.function" + }, + { + "foreground": "4271ae", + "token": "meta.function-call" + }, + { + "foreground": "4271ae", + "token": "support.function" + }, + { + "foreground": "4271ae", + "token": "keyword.other.special-method" + }, + { + "foreground": "4271ae", + "token": "meta.block-level" + }, + { + "foreground": "4271ae", + "token": "markup.changed.git_gutter" + }, + { + "foreground": "8959a8", + "token": "keyword" + }, + { + "foreground": "8959a8", + "token": "storage" + }, + { + "foreground": "8959a8", + "token": "storage.type" + }, + { + "foreground": "ffffff", + "background": "c82829", + "token": "invalid" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.separator" + }, + { + "foreground": "ffffff", + "background": "8959a8", + "token": "invalid.deprecated" + }, + { + "foreground": "ffffff", + "token": "markup.inserted.diff" + }, + { + "foreground": "ffffff", + "token": "markup.deleted.diff" + }, + { + "foreground": "ffffff", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "ffffff", + "token": "meta.diff.header.from-file" + }, + { + "background": "718c00", + "token": "markup.inserted.diff" + }, + { + "background": "718c00", + "token": "meta.diff.header.to-file" + }, + { + "background": "c82829", + "token": "markup.deleted.diff" + }, + { + "background": "c82829", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.diff.header.from-file" + }, + { + "foreground": "ffffff", + "background": "4271ae", + "token": "meta.diff.header.to-file" + }, + { + "foreground": "3e999f", + "fontStyle": "italic", + "token": "meta.diff.range" + } + ], + "colors": { + "editor.foreground": "#4D4D4C", + "editor.background": "#FFFFFF", + "editor.selectionBackground": "#D6D6D6", + "editor.lineHighlightBackground": "#EFEFEF", + "editorCursor.foreground": "#AEAFAD", + "editorWhitespace.foreground": "#D1D1D1" + } +} \ No newline at end of file diff --git a/apps/desktop/src/renderer/src/lib/monaco-setup.ts b/apps/desktop/src/renderer/src/lib/monaco-setup.ts index 605793eb..06c986d1 100644 --- a/apps/desktop/src/renderer/src/lib/monaco-setup.ts +++ b/apps/desktop/src/renderer/src/lib/monaco-setup.ts @@ -15,6 +15,24 @@ import * as tsLang from 'monaco-editor/esm/vs/language/typescript/monaco.contrib import * as jsonLang from 'monaco-editor/esm/vs/language/json/monaco.contribution.js'; import * as cssLang from 'monaco-editor/esm/vs/language/css/monaco.contribution.js'; import * as htmlLang from 'monaco-editor/esm/vs/language/html/monaco.contribution.js'; +// 第三方编辑器主题(IStandaloneThemeData 形状,vendored 自 monaco-themes,见 editor-themes/NOTICE.md), +// 下方经 defineTheme 注册供选择。id 与 @meebox/shared EDITOR_THEME_OPTIONS 对齐;vs / vs-dark / hc-* +// 为 Monaco 内置、无需注册。就地内置而非 npm 依赖:monaco-themes 的 exports 未暴露 ./themes/* 子路径。 +import githubLight from './editor-themes/github-light.json'; +import githubDark from './editor-themes/github-dark.json'; +import monokai from './editor-themes/monokai.json'; +import dracula from './editor-themes/dracula.json'; +import nord from './editor-themes/nord.json'; +import nightOwl from './editor-themes/night-owl.json'; +import tomorrow from './editor-themes/tomorrow.json'; +import tomorrowNight from './editor-themes/tomorrow-night.json'; +import solarizedLight from './editor-themes/solarized-light.json'; +import solarizedDark from './editor-themes/solarized-dark.json'; +import cobalt2 from './editor-themes/cobalt2.json'; +import oceanicNext from './editor-themes/oceanic-next.json'; +// VS Code 内置 2026 默认主题(转换自 microsoft/vscode theme-defaults,已解析 include 链并转为 Monaco 形状)。 +import dark2026 from './editor-themes/dark-2026.json'; +import light2026 from './editor-themes/light-2026.json'; // Vite 的 ?worker import 返回一个可 new 的 Worker 构造类。 self.MonacoEnvironment = { @@ -25,6 +43,28 @@ self.MonacoEnvironment = { loader.config({ monaco }); +// 注册第三方编辑器主题(id → 主题数据)。Monaco 内置 vs / vs-dark / hc-* 不在此列。JSON 的 base +// 字段类型为 string,与 IStandaloneThemeData 的字面量联合不完全兼容,经 unknown 转换取用。 +const CUSTOM_EDITOR_THEMES: ReadonlyArray = [ + ['github-light', githubLight], + ['github-dark', githubDark], + ['monokai', monokai], + ['dracula', dracula], + ['nord', nord], + ['night-owl', nightOwl], + ['tomorrow', tomorrow], + ['tomorrow-night', tomorrowNight], + ['solarized-light', solarizedLight], + ['solarized-dark', solarizedDark], + ['cobalt2', cobalt2], + ['oceanic-next', oceanicNext], + ['dark-2026', dark2026], + ['light-2026', light2026], +]; +for (const [id, data] of CUSTOM_EDITOR_THEMES) { + monaco.editor.defineTheme(id, data as unknown as monaco.editor.IStandaloneThemeData); +} + /** * 关掉 4 个「带 worker 后端语言服务」的语言族的全部特性:typescript/javascript(ts.worker)、 * json(json.worker)、css/scss/less(css.worker)、html/handlebars/razor(html.worker)。 diff --git a/apps/desktop/src/renderer/src/main.tsx b/apps/desktop/src/renderer/src/main.tsx index 996494b4..f6f5c598 100644 --- a/apps/desktop/src/renderer/src/main.tsx +++ b/apps/desktop/src/renderer/src/main.tsx @@ -6,6 +6,9 @@ import materialIconTheme from '@iconify-json/material-icon-theme/icons.json'; // 两个懒模块,仅在首次看 diff / 行内代码上下文时才拉取,避免阻塞窗口首帧。 // i18n 必须在 App 之前 import:副作用里同步 init i18next,保证首帧渲染前 t() 可用。 import './i18n'; +// theme 同样在 App 之前 import:副作用里按 localStorage 缓存同步定下首帧主题(写 data-theme), +// 避免浅色用户启动先闪一帧深色。 +import './theme'; import App from './App'; import './App.scss'; diff --git a/apps/desktop/src/renderer/src/stores/editor-appearance-store.ts b/apps/desktop/src/renderer/src/stores/editor-appearance-store.ts new file mode 100644 index 00000000..b9600ea7 --- /dev/null +++ b/apps/desktop/src/renderer/src/stores/editor-appearance-store.ts @@ -0,0 +1,53 @@ +import { useSyncExternalStore } from 'react'; +import type { EditorTheme } from '@meebox/shared'; + +/** + * 编辑器外观(Monaco 配色主题 + 等宽字体)的渲染层共享态。App 从 config.appearance 写入,深层的 Monaco + * 组件(DiffPane / InlineCodeContext)经 useEditorAppearance 读出 —— 避免逐层透传 props。 + * + * 与 selection-store 同模(模块级状态 + Set + useSyncExternalStore):纯本地、无 IPC、无 + * hydrate。持久化与写盘走 config(IPC config:setEditorAppearance),本 store 只承载「当前生效值」。 + */ +export interface EditorAppearanceState { + /** 编辑器配色主题偏好:'auto' 跟随 GUI 深 / 浅色,其余为具体 Monaco 主题名。 */ + editorTheme: EditorTheme; + /** 等宽字体族(空 = 用内置 mono 字体栈)。 */ + fontFamily: string; + /** 字号(px,未做平台微调的基准值)。 */ + fontSize: number; +} + +let state: EditorAppearanceState = { editorTheme: 'auto', fontFamily: '', fontSize: 14 }; +const subscribers = new Set<() => void>(); + +function notify(): void { + for (const cb of subscribers) cb(); +} + +const store = { + getSnapshot: (): EditorAppearanceState => state, + subscribe: (cb: () => void): (() => void) => { + subscribers.add(cb); + return () => { + subscribers.delete(cb); + }; + }, +}; + +/** 写入当前编辑器外观(App 在 config 变化时调用)。各字段相等则跳过,避免无谓重渲。 */ +export function setEditorAppearance(next: EditorAppearanceState): void { + if ( + next.editorTheme === state.editorTheme && + next.fontFamily === state.fontFamily && + next.fontSize === state.fontSize + ) { + return; + } + state = next; + notify(); +} + +/** 读当前编辑器外观(Monaco 组件用)。 */ +export function useEditorAppearance(): EditorAppearanceState { + return useSyncExternalStore(store.subscribe, store.getSnapshot); +} diff --git a/apps/desktop/src/renderer/src/styles/_palette.scss b/apps/desktop/src/renderer/src/styles/_palette.scss new file mode 100644 index 00000000..988b63ae --- /dev/null +++ b/apps/desktop/src/renderer/src/styles/_palette.scss @@ -0,0 +1,99 @@ +// 原始调色板(标准色层 / Tier 1):按色相family 组织的「标准色」,是全应用配色的唯一色值真相源。 +// 上层语义 token(_theme.scss)只引用这里的原色,绝不再写裸 hex —— 主题切换时换的是「语义 → 原色」 +// 的映射,而非散落各处的色值。 +// +// 命名:`$-`,step 越大越深(与 Tailwind 习惯一致,仅作 family 内排序,非统一感知刻度)。 +// 取色沿用 VS Code Dark+ / Tailwind / Material 既有标准值,重构期严格保持暗色主题像素级一致。 +// 纯变量、无 CSS 输出;经 `@use './palette' as *;` 拉取。 + +// ===== 中性灰阶(gray / slate)===== +// 暗色主题的底 / 边 / 字面。深 → 浅。slate 一档带轻微蓝灰,单列出以区分纯灰。 +$gray-900: #181818; // 最深:侧栏分组头 +$gray-880: #1a1a1b; // 输入区等更深一档 +$gray-850: #1e1e1e; // app shell / body +$gray-840: #1f1f20; // 侧栏 / 列表底 +$gray-820: #252526; // 浮层 / 弹出菜单 +$gray-780: #2a2d2e; // hover 高亮 / avatar 底 +$gray-760: #2d2d30; // 输入框 / chip 默认底 / 弱边框 +$gray-680: #3e3e42; // 默认边框 +$gray-600: #4d4d4d; // 滚动条滑块 +$gray-540: #5e5e5e; // 滚动条 hover +$gray-500: #6e6e6e; // 极弱 placeholder 字 +$gray-480: #707070; // 滚动条 active +$gray-420: #858585; // 次级文字 +$gray-200: #cccccc; // 主文字 +$gray-160: #d4d4d4; // body 文字 +$slate-500: #6e7681; // 更弱文字(blame / footer)/ 折叠斜纹 +$white: #ffffff; +$black: #000000; + +// ===== 蓝(blue)===== +$blue-900: #094771; // 列表项选中底(VS Code activeList) +$blue-700: #0e639c; // 主蓝 accent / primary +$blue-600: #1177bb; // primary hover(提亮一档) +$blue-400: #60a5fa; // 文件 copied 状态点 +$blue-300: #6cb6ff; // 链接 / 提示 / cache 命中 + +// ===== 绿(green / lime)===== +$green-700: #16825d; // 状态栏 system OK 深绿 +$green-600: #16a34a; // PR approved 绿(Tailwind green-600) +$green-500: #4caf50; // 文件 added 状态点(Material green-500) +$green-450: #22c55e; // token ↑输入(Tailwind green-500) +$green-400: #5fa56d; // 草稿已发布底(仅作浅底基色) +$green-300: #73c991; // git added 装饰绿 +$lime-700: #487e02; // blame 改动行绿条(偏橄榄) + +// ===== 琥珀 / 黄(amber / yellow)===== +$amber-600: #d97706; // warning 饱和琥珀(Tailwind amber-600) +$amber-500: #f59e0b; // 文件 modified 状态点 / 冲突底基色(Tailwind amber-500) +$amber-450: #e59e1e; // 待办 / pending 底基色 +$amber-400: #fbbf24; // 亮琥珀,纯文字告警 +$amber-300: #e2c08d; // git modified 装饰(tan) +$yellow-300: #ffd54f; // diff 搜索命中高亮基色(Material amber) + +// ===== 红 / 橙(red)===== +$red-700: #c72e0f; // 错误实底 / 删除按钮(高饱和) +$red-600: #c74e39; // git deleted 装饰 +$red-550: #dc2626; // 文件 deleted 状态点(Tailwind red-600) +$red-500: #e8512e; // ghost 危险按钮描边 / 文字 +$red-450: #ef4444; // token ↓输出(Tailwind red-500) +$red-300: #f48771; // 错误文案 / 红边框(salmon) + +// ===== 紫(purple)===== +$purple-400: #a78bfa; // 文件 renamed 状态点(Tailwind violet-400) + +// ============================================================================ +// 浅色主题补充原色(Light theme additions) +// 浅色主题在白底上需要更深 / 更饱和的品牌色以保证对比度,单设这些步级;浅色中性「纸面」自成一段 +// 由亮到暗续在灰阶里(数字越大越深,故均小于上面暗色段的最浅一档 $gray-160)。深色文字直接复用 +// 上面的近黑灰($gray-840 / $gray-820)。VS Code Light+ 取色对齐。 +// ============================================================================ + +// 浅色中性「纸面」灰阶(亮 → 暗) +$gray-0: #ffffff; // 最亮:编辑器 / 浮层底 +$gray-30: #f8f8f8; // 浅色 app shell +$gray-60: #f3f3f3; // 浅色侧栏 / 列表底 +$gray-90: #ececec; // 浅色更深一档(输入区) +$gray-120: #e8e8e8; // 浅色 hover / 分组头 +$gray-150: #e0e0e0; // 浅色弱边框 / avatar 底 +$gray-220: #cfcfcf; // 浅色默认边框 +$gray-260: #c1c1c1; // 浅色滚动条滑块 +$gray-340: #a8a8a8; // 浅色滚动条 hover / 极弱文字 +$gray-380: #909090; // 浅色滚动条 active / 折叠灰 + +// 浅色品牌步级(白底高对比) +$blue-800: #005fb8; // 浅色 accent / primary +$blue-750: #0a4f9e; // 浅色 primary hover(压暗一档) +$blue-650: #0a66c2; // 浅色链接 / info / cache +$blue-500: #2563eb; // 浅色文件 copied 状态点 +$blue-100: #cfe3fb; // 浅色列表选中底(承深色文字) +$green-650: #15803d; // 浅色 approved / token ↑输入 +$green-550: #1a7f37; // 浅色 git added 装饰 +$green-480: #2e9e4f; // 浅色文件 added 状态点 +$amber-700: #b45309; // 浅色 warning / 纯文字告警 +$amber-650: #9a6700; // 浅色 git modified 装饰 +$amber-550: #d18616; // 浅色文件 modified 状态点 +$red-680: #b31d28; // 浅色 git deleted 装饰 +$red-650: #cd3131; // 浅色 danger / needs-work 文字(VS Code Light error) +$red-620: #c0392b; // 浅色 ghost 危险按钮描边 / 文字 +$purple-500: #8b5cf6; // 浅色文件 renamed 状态点 diff --git a/apps/desktop/src/renderer/src/styles/_theme.scss b/apps/desktop/src/renderer/src/styles/_theme.scss new file mode 100644 index 00000000..0ad914bb --- /dev/null +++ b/apps/desktop/src/renderer/src/styles/_theme.scss @@ -0,0 +1,205 @@ +// 主题层(语义层 / Tier 2):把语义 token 映射到 _palette.scss 的标准色,发射为 CSS 自定义属性 +// (CSS custom properties),使「语义 → 色值」可在运行期整体切换 —— 这是深色 / 浅色主题切换的基座。 +// +// - 默认(:root)即当前**暗色**主题,重构期与旧 SCSS 像素级一致。 +// - 后续浅色主题在此追加 `:root[data-theme='light'] { ... }` 覆盖同名变量即可,无需触碰任何使用处。 +// - 业务样式不直接引用本文件的变量名,而经 _tokens.scss 的 `$token: var(--token)` 桥接(使用处零改动)。 +// +// 半透明叠加:少数语义色需在使用处按不同 alpha 叠加(`rgb(var(--rgb-x) / a)`),故额外发射其 RGB 通道 +// 三元组(`--rgb-*`)。预先算好的固定 alpha 浅底仍以字面 rgba() 保留语义 token,求暗色精确还原。 + +@use 'sass:color'; +@use './palette' as *; + +// 取色的 RGB 通道三元组(空格分隔,供 `rgb( / )`)。以 palette 原色为唯一来源。 +@function rgb-channels($c) { + @return #{color.channel($c, 'red', $space: rgb)} + #{color.channel($c, 'green', $space: rgb)} + #{color.channel($c, 'blue', $space: rgb)}; +} + +:root { + // ===== 背景 ===== + --bg-app: #{$gray-850}; + --bg-white-fade: rgba(255, 255, 255, 0.12); // icon-btn hover / count-pill 底 + --bg-panel: #{$gray-840}; + --bg-panel-alt: #{$gray-880}; + --bg-elev: #{$gray-820}; + --bg-surface: #{$gray-760}; + --bg-hover: #{$gray-780}; + --bg-selected: #{$blue-900}; + --bg-group-header: #{$gray-900}; + + // ===== 边框 ===== + --border-default: #{$gray-680}; + --border-default-fade: rgba(62, 62, 66, 0.5); // blame row 内分隔线 + --border-muted: #{$gray-760}; + + // ===== 文字 ===== + --text-primary: #{$gray-200}; + --text-body: #{$gray-160}; + --text-muted: #{$gray-420}; + --text-subtle: #{$slate-500}; + --text-dim: #{$gray-500}; + --text-on-accent: #{$white}; + + // ===== 语义色(动作 / 状态)===== + --color-accent: #{$blue-700}; + --color-accent-hover: #{$blue-600}; + --color-accent-bg-fade: rgba(14, 99, 156, 0.18); + --color-accent-strong-fade: rgba(14, 99, 156, 0.5); // resize handle hover/active + --color-info: #{$blue-300}; + --color-success: #{$green-700}; + --color-approved: #{$green-600}; + --color-warning: #{$amber-600}; + --color-warning-bright: #{$amber-400}; + --color-danger: #{$red-300}; + --color-danger-bg: #{$red-700}; + --color-danger-strong: #{$red-500}; + --color-danger-strong-fade: rgba(232, 81, 46, 0.12); // ghost 危险按钮 hover 浅红底 + --color-token-in: #{$green-450}; + --color-token-out: #{$red-450}; + --color-token-cache: #{$blue-300}; + + // 语义色浅底(chip / banner 背景,与对应主色同色相) + --color-accent-bg-hover: rgba(14, 99, 156, 0.28); + --color-approved-fade: rgba(22, 163, 74, 0.18); + --color-approved-fade-soft: rgba(22, 163, 74, 0.1); + --color-warning-fade: rgba(217, 119, 6, 0.18); + --color-danger-fade: rgba(244, 135, 113, 0.08); + --color-danger-border: rgba(244, 135, 113, 0.35); + + // off-palette 状态浅底(与主色略有出入,暂各自具名,待后续与主色收敛) + --color-conflict-fade: rgba(245, 158, 11, 0.18); // 冲突 / needsWork chip 填充 + --color-pending-fade: rgba(229, 158, 30, 0.15); // 待办 / 草稿 pending 填充 + --color-posted-fade: rgba(95, 165, 109, 0.15); // 草稿已发布填充 + --color-search-hit: rgba(255, 213, 79, 0.42); // diff 搜索命中高亮 + + // ===== Git decoration 配色(跟 Monaco / VS Code 一致)===== + --git-added: #{$green-300}; + --git-added-bg-fade: rgba(115, 199, 145, 0.16); + --git-modified: #{$amber-300}; + --git-deleted: #{$red-600}; + --git-needs-work-fade: rgba(199, 78, 57, 0.18); + --git-needs-work-fg: #{$red-300}; + --blame-change: #{$lime-700}; // PR 改动行绿条 + --blame-fold: #{$slate-500}; // 折叠占位斜纹灰 + + // ===== 文件改动状态点 ===== + --file-status-added: #{$green-500}; + --file-status-modified: #{$amber-500}; + --file-status-deleted: #{$red-550}; + --file-status-renamed: #{$purple-400}; + --file-status-copied: #{$blue-400}; + + // ===== Avatar / 装饰 ===== + --avatar-bg-default: #{$gray-780}; + + // ===== 滚动条(webkit)===== + --scrollbar-thumb: #{$gray-600}; + --scrollbar-thumb-hover: #{$gray-540}; + --scrollbar-thumb-active: #{$gray-480}; + + // ===== RGB 通道三元组(供使用处 `rgb(var(--rgb-x) / )` 半透明叠加)===== + --rgb-accent: #{rgb-channels($blue-700)}; + --rgb-danger: #{rgb-channels($red-300)}; + --rgb-warning: #{rgb-channels($amber-600)}; + --rgb-approved: #{rgb-channels($green-600)}; + --rgb-git-modified: #{rgb-channels($amber-300)}; + --rgb-blame-change: #{rgb-channels($lime-700)}; + --rgb-blame-fold: #{rgb-channels($slate-500)}; +} + +// ============================================================================ +// 浅色主题:覆盖同名语义变量。偏好解析为 light 时 renderer 写 documentElement[data-theme='light'] +// 触发本块。白底需更深 / 更饱和的品牌色保对比;半透明叠加(白雾 hover / 分隔线)翻成黑雾,否则白底看不见。 +// ============================================================================ +:root[data-theme='light'] { + // ===== 背景 ===== + --bg-app: #{$gray-30}; + --bg-white-fade: rgba(0, 0, 0, 0.06); // icon-btn hover:白底改黑雾 + --bg-panel: #{$gray-60}; + --bg-panel-alt: #{$gray-90}; + --bg-elev: #{$gray-0}; + --bg-surface: #{$gray-0}; + --bg-hover: #{$gray-120}; + --bg-selected: #{$blue-100}; + --bg-group-header: #{$gray-120}; + + // ===== 边框 ===== + --border-default: #{$gray-220}; + --border-default-fade: rgba(0, 0, 0, 0.08); + --border-muted: #{$gray-150}; + + // ===== 文字 ===== + --text-primary: #{$gray-840}; + --text-body: #{$gray-820}; + --text-muted: #{$gray-500}; + --text-subtle: #{$gray-420}; + --text-dim: #{$gray-340}; + --text-on-accent: #{$white}; + + // ===== 语义色(动作 / 状态)===== + --color-accent: #{$blue-800}; + --color-accent-hover: #{$blue-750}; + --color-accent-bg-fade: rgba(0, 95, 184, 0.1); + --color-accent-strong-fade: rgba(0, 95, 184, 0.4); + --color-info: #{$blue-650}; + --color-success: #{$green-700}; + --color-approved: #{$green-650}; + --color-warning: #{$amber-700}; + --color-warning-bright: #{$amber-700}; + --color-danger: #{$red-650}; + --color-danger-bg: #{$red-700}; + --color-danger-strong: #{$red-620}; + --color-danger-strong-fade: rgba(192, 57, 43, 0.1); + --color-token-in: #{$green-650}; + --color-token-out: #{$red-550}; + --color-token-cache: #{$blue-650}; + + --color-accent-bg-hover: rgba(0, 95, 184, 0.16); + --color-approved-fade: rgba(21, 128, 61, 0.12); + --color-approved-fade-soft: rgba(21, 128, 61, 0.08); + --color-warning-fade: rgba(180, 83, 9, 0.12); + --color-danger-fade: rgba(205, 49, 49, 0.08); + --color-danger-border: rgba(205, 49, 49, 0.35); + + --color-conflict-fade: rgba(180, 83, 9, 0.14); + --color-pending-fade: rgba(180, 83, 9, 0.12); + --color-posted-fade: rgba(21, 128, 61, 0.12); + --color-search-hit: rgba(250, 204, 21, 0.55); + + // ===== Git decoration ===== + --git-added: #{$green-550}; + --git-added-bg-fade: rgba(26, 127, 55, 0.12); + --git-modified: #{$amber-650}; + --git-deleted: #{$red-680}; + --git-needs-work-fade: rgba(179, 29, 40, 0.12); + --git-needs-work-fg: #{$red-650}; + --blame-change: #{$lime-700}; + --blame-fold: #{$gray-380}; + + // ===== 文件改动状态点 ===== + --file-status-added: #{$green-480}; + --file-status-modified: #{$amber-550}; + --file-status-deleted: #{$red-550}; + --file-status-renamed: #{$purple-500}; + --file-status-copied: #{$blue-500}; + + // ===== Avatar / 装饰 ===== + --avatar-bg-default: #{$gray-150}; + + // ===== 滚动条 ===== + --scrollbar-thumb: #{$gray-260}; + --scrollbar-thumb-hover: #{$gray-340}; + --scrollbar-thumb-active: #{$gray-380}; + + // ===== RGB 通道三元组(随浅色品牌基色重置)===== + --rgb-accent: #{rgb-channels($blue-800)}; + --rgb-danger: #{rgb-channels($red-650)}; + --rgb-warning: #{rgb-channels($amber-700)}; + --rgb-approved: #{rgb-channels($green-650)}; + --rgb-git-modified: #{rgb-channels($amber-650)}; + --rgb-blame-change: #{rgb-channels($lime-700)}; + --rgb-blame-fold: #{rgb-channels($gray-380)}; +} diff --git a/apps/desktop/src/renderer/src/styles/_tokens.scss b/apps/desktop/src/renderer/src/styles/_tokens.scss index a27f53c3..96becff8 100644 --- a/apps/desktop/src/renderer/src/styles/_tokens.scss +++ b/apps/desktop/src/renderer/src/styles/_tokens.scss @@ -1,95 +1,97 @@ -// 设计 token 中心:颜色 / 字号 / 圆角 / 间距 / 行高 / z-index 阶梯 +// 设计 token 桥接层:颜色 / 字号 / 圆角 / 间距 / 行高 / z-index 阶梯 // 各 .scss 文件用 `@use './tokens' as *;` 拉到本地作用域。 // +// 颜色三层结构(见 _palette.scss / _theme.scss): +// - _palette.scss 原始标准色(Tier 1,唯一色值真相源) +// - _theme.scss 语义 → 原色,发射为 CSS 自定义属性(Tier 2,运行期可整体换主题) +// - 本文件 把语义 SCSS 变量桥接到对应 CSS 自定义属性(`$token: var(--token)`), +// 使用处保持 `background: $bg-app` 等旧写法不变,编译即输出 `var(--bg-app)`。 +// // 规则: -// - 颜色按语义分组 (bg / border / text / accent / git-decoration),不按色值命名 -// - 字号 / 间距用 t-shirt 尺寸 (xs/sm/md/lg) -// - 命名跟 VS Code Dark+ 主题对齐,方便日后增加 light 主题做映射 +// - 颜色一律桥接到 var(--*),绝不在此写裸 hex —— 改色去 _palette.scss / _theme.scss。 +// - 需在使用处按 alpha 叠加的少数色,用 `rgb(var(--rgb-*) / )`(通道三元组见 _theme.scss)。 +// - 字号 / 间距 / 圆角 / z-index 等非颜色 token 仍为编译期常量(不参与主题切换),留在本文件。 // ===== 背景色 ===== -$bg-app: #1e1e1e; // body / app shell -$bg-white-fade: rgba(255, 255, 255, 0.12); // icon-btn hover / count-pill 底 -$bg-panel: #1f1f20; // 侧栏 / 文件列表 / blame 列底 -$bg-panel-alt: #1a1a1b; // chat-pane 输入区等更深一档 -$bg-elev: #252526; // 浮层 / 弹出菜单 -$bg-surface: #2d2d30; // 输入框 / chip 默认底 / 代码块底 -$bg-hover: #2a2d2e; // hover 高亮 -$bg-selected: #094771; // 列表项选中(VS Code activeList) -$bg-group-header: #181818; // 侧栏 PR 分组头,比 panel 更深一档 +$bg-app: var(--bg-app); +$bg-white-fade: var(--bg-white-fade); +$bg-panel: var(--bg-panel); +$bg-panel-alt: var(--bg-panel-alt); +$bg-elev: var(--bg-elev); +$bg-surface: var(--bg-surface); +$bg-hover: var(--bg-hover); +$bg-selected: var(--bg-selected); +$bg-group-header: var(--bg-group-header); // ===== 边框 ===== -$border-default: #3e3e42; -$border-default-fade: rgba(62, 62, 66, 0.5); // blame row 内分隔线 -$border-muted: #2d2d30; +$border-default: var(--border-default); +$border-default-fade: var(--border-default-fade); +$border-muted: var(--border-muted); // ===== 文字 ===== -$text-primary: #cccccc; -$text-body: #d4d4d4; // body 默认 -$text-muted: #858585; -$text-subtle: #6e7681; // 更弱:blame / footer hint -$text-dim: #6e6e6e; // 几乎不可见的 placeholder 风 -$text-on-accent: #ffffff; +$text-primary: var(--text-primary); +$text-body: var(--text-body); +$text-muted: var(--text-muted); +$text-subtle: var(--text-subtle); +$text-dim: var(--text-dim); +$text-on-accent: var(--text-on-accent); // ===== 语义色 (动作 / 状态) ===== -$color-accent: #0e639c; // VS Code 主蓝,active / primary -$color-accent-hover: #1177bb; // primary 按钮 hover(比 accent 提亮一档) -$color-accent-bg-fade: rgba(14, 99, 156, 0.18); -$color-accent-strong-fade: rgba(14, 99, 156, 0.5); // resize handle hover/active -$color-info: #6cb6ff; // 浅蓝,链接 / 提示 -$color-success: #16825d; // 状态栏 remote 风格深绿 (system OK) -$color-approved: #16a34a; // PR review "approved/通过" 专用绿 (Tailwind green-600) -$color-warning: #d97706; // PR review "needs work / 需修改" 饱和琥珀 (Tailwind amber-600,对齐 $color-approved 重量) -$color-warning-bright: #fbbf24; // 亮琥珀,只用于纯文字告警 (conflict-tag / diff-binary),无背景 -$color-danger: #f48771; // 错误文案 / 红边框 -$color-danger-bg: #c72e0f; // 错误 chip / 模态删除按钮实底(高饱和) -// ghost 危险按钮(删除评论 / 草稿 / 连接 / LLM、停止、拒绝等)的描边 + 文字饱和红: -// 与实底 $color-danger-bg(#c72e0f) 同色相、提亮以保暗底可读,比 $color-danger 更饱和、警示力更强 -$color-danger-strong: #e8512e; -$color-danger-strong-fade: rgba(232, 81, 46, 0.12); // ghost 危险按钮 hover 浅红底 -$color-token-in: #22c55e; // token 用量 ↑输入 (Tailwind green-500) -$color-token-out: #ef4444; // token 用量 ↓输出 (Tailwind red-500) -$color-token-cache: #6cb6ff; // token 用量 缓存命中(cache_read) 柱体图标,浅蓝 - -// 语义色浅底 (chip / banner 背景,与对应主色同色相;chat 卡片大量复用) -$color-accent-bg-hover: rgba(14, 99, 156, 0.28); // 蓝调 chip hover 加深 (rule-chip) -$color-approved-fade: rgba(22, 163, 74, 0.18); // approved chip 浅绿底 -$color-approved-fade-soft: rgba(22, 163, 74, 0.1); // 代码 diff improved 块浅绿底 (比 chip 更淡) -$color-warning-fade: rgba(217, 119, 6, 0.18); // warning chip 浅琥珀底 -$color-danger-fade: rgba(244, 135, 113, 0.08); // 错误 banner / existing 代码块 浅红底 -$color-danger-border: rgba(244, 135, 113, 0.35); // 错误 banner 描边 - -// off-palette 状态浅底(amber/green/yellow 与主色略有出入,暂各自具名以消除硬编码,待后续与主色收敛) -$color-conflict-fade: rgba(245, 158, 11, 0.18); // 冲突 / needsWork chip 填充 (conflict-tag / pr-activity needsWork) -$color-pending-fade: rgba(229, 158, 30, 0.15); // 待办 / 草稿 pending 填充 (tab badge / drafts pending) -$color-posted-fade: rgba(95, 165, 109, 0.15); // 草稿已发布填充 -$color-search-hit: rgba(255, 213, 79, 0.42); // diff 搜索命中高亮 - -// ===== Git decoration 配色 (跟 Monaco / VS Code 一致) ===== -$git-added: #73c991; -$git-added-bg-fade: rgba(115, 199, 145, 0.16); -$git-modified: #e2c08d; -$git-deleted: #c74e39; -$git-needs-work-fade: rgba(199, 78, 57, 0.18); -$git-needs-work-fg: #f48771; -// blame 列专属(off-palette):PR 改动行绿条(对齐 Monaco diff added 装饰绿)+ 折叠占位斜纹灰 -$blame-change: #487e02; -$blame-fold: #6e7681; - -// ===== 文件改动状态点 (文件树右栏 8px 圆点) ===== -// 比 $git-* 装饰色更亮的 Material 系:小圆点上比装饰色更易辨认。typechange 用 $text-muted -$file-status-added: #4caf50; -$file-status-modified: #f59e0b; -$file-status-deleted: #dc2626; -$file-status-renamed: #a78bfa; -$file-status-copied: #60a5fa; +$color-accent: var(--color-accent); +$color-accent-hover: var(--color-accent-hover); +$color-accent-bg-fade: var(--color-accent-bg-fade); +$color-accent-strong-fade: var(--color-accent-strong-fade); +$color-info: var(--color-info); +$color-success: var(--color-success); +$color-approved: var(--color-approved); +$color-warning: var(--color-warning); +$color-warning-bright: var(--color-warning-bright); +$color-danger: var(--color-danger); +$color-danger-bg: var(--color-danger-bg); +$color-danger-strong: var(--color-danger-strong); +$color-danger-strong-fade: var(--color-danger-strong-fade); +$color-token-in: var(--color-token-in); +$color-token-out: var(--color-token-out); +$color-token-cache: var(--color-token-cache); + +// 语义色浅底 (chip / banner 背景) +$color-accent-bg-hover: var(--color-accent-bg-hover); +$color-approved-fade: var(--color-approved-fade); +$color-approved-fade-soft: var(--color-approved-fade-soft); +$color-warning-fade: var(--color-warning-fade); +$color-danger-fade: var(--color-danger-fade); +$color-danger-border: var(--color-danger-border); + +// off-palette 状态浅底 +$color-conflict-fade: var(--color-conflict-fade); +$color-pending-fade: var(--color-pending-fade); +$color-posted-fade: var(--color-posted-fade); +$color-search-hit: var(--color-search-hit); + +// ===== Git decoration 配色 ===== +$git-added: var(--git-added); +$git-added-bg-fade: var(--git-added-bg-fade); +$git-modified: var(--git-modified); +$git-deleted: var(--git-deleted); +$git-needs-work-fade: var(--git-needs-work-fade); +$git-needs-work-fg: var(--git-needs-work-fg); +$blame-change: var(--blame-change); +$blame-fold: var(--blame-fold); + +// ===== 文件改动状态点 ===== +$file-status-added: var(--file-status-added); +$file-status-modified: var(--file-status-modified); +$file-status-deleted: var(--file-status-deleted); +$file-status-renamed: var(--file-status-renamed); +$file-status-copied: var(--file-status-copied); // ===== Avatar / Initials 等装饰 ===== -$avatar-bg-default: #2a2d2e; +$avatar-bg-default: var(--avatar-bg-default); // ===== 滚动条 (webkit) ===== -$scrollbar-thumb: #4d4d4d; -$scrollbar-thumb-hover: #5e5e5e; -$scrollbar-thumb-active: #707070; +$scrollbar-thumb: var(--scrollbar-thumb); +$scrollbar-thumb-hover: var(--scrollbar-thumb-hover); +$scrollbar-thumb-active: var(--scrollbar-thumb-active); // ===== 字号 ===== // 整体设计基线在 14px:body 默认 / Monaco 编辑器都走 $fs-lg=14。 @@ -130,4 +132,6 @@ $z-modal: 1000; $z-modal-nested: 1100; // ===== 字体族 ===== -$font-mono: var(--vscode-editor-font-family, 'Consolas', monospace); +// 等宽字体优先取用户配置(--editor-font-family,由 renderer 按 config 写入 documentElement), +// 未配置时回落 Monaco 注入的 --vscode-editor-font-family,再回落内置 Consolas / monospace。 +$font-mono: var(--editor-font-family, var(--vscode-editor-font-family, 'Consolas', monospace)); diff --git a/apps/desktop/src/renderer/src/styles/base.scss b/apps/desktop/src/renderer/src/styles/base.scss index 3dac08fb..62c5b403 100644 --- a/apps/desktop/src/renderer/src/styles/base.scss +++ b/apps/desktop/src/renderer/src/styles/base.scss @@ -1,4 +1,5 @@ @use './tokens' as *; +@use './theme'; // 发射 :root 主题变量块(语义 → 标准色);本文件经 App.scss 首位引入,确保只发射一次 * { box-sizing: border-box; diff --git a/apps/desktop/src/renderer/src/styles/common/modal.scss b/apps/desktop/src/renderer/src/styles/common/modal.scss index 91efe1cc..e9f7a2e5 100644 --- a/apps/desktop/src/renderer/src/styles/common/modal.scss +++ b/apps/desktop/src/renderer/src/styles/common/modal.scss @@ -62,8 +62,8 @@ // 让左导航与右侧内容各得其所。定高(受 .modal 的 max-height: 84vh 上限约束), // 使切换分区时模态尺寸恒定、右侧内容区独立滚动而非整体撑高。 .modal-lg { - max-width: 880px; - height: 720px; + max-width: 760px; + height: 600px; } // ConfirmModal: 跟 SettingsModal 共用 .modal-backdrop/.modal/.modal-header,加几条 @@ -99,6 +99,13 @@ } } +// 分区分隔线:在分区上方画一条细线 + 留白,把它与上方分区视觉分组(如设置「常规」里编辑器配置与 +// 语言 / 主题分隔)。 +.modal-section-divider { + border-top: 1px solid $border-default; + padding-top: $space-8; +} + // 区块标题行:标题左、操作按钮(如"+ 添加连接")右,省纵向空间。h4 去掉自身 // 下边距改由本行统一控制 .modal-section-head { diff --git a/apps/desktop/src/renderer/src/styles/features/chat/statusbar.scss b/apps/desktop/src/renderer/src/styles/features/chat/statusbar.scss index 0d22a0a7..5240171b 100644 --- a/apps/desktop/src/renderer/src/styles/features/chat/statusbar.scss +++ b/apps/desktop/src/renderer/src/styles/features/chat/statusbar.scss @@ -155,7 +155,7 @@ button.statusbar-pragent-chip { cursor: pointer; &:hover { - background: rgba($color-danger, 0.15); + background: rgb(var(--rgb-danger) / 0.15); color: $color-danger; } } diff --git a/apps/desktop/src/renderer/src/styles/features/diff/blame.scss b/apps/desktop/src/renderer/src/styles/features/diff/blame.scss index 0d6643d7..26e4264f 100644 --- a/apps/desktop/src/renderer/src/styles/features/diff/blame.scss +++ b/apps/desktop/src/renderer/src/styles/features/diff/blame.scss @@ -112,7 +112,7 @@ right: 0; padding-left: 10px; border-left: 3px solid $blame-change; - background: rgba($blame-change, 0.08); + background: rgb(var(--rgb-blame-change) / 0.08); pointer-events: auto; box-sizing: border-box; } @@ -124,8 +124,8 @@ right: 0; background: repeating-linear-gradient( -45deg, - rgba($blame-fold, 0.08) 0, - rgba($blame-fold, 0.08) 4px, + rgb(var(--rgb-blame-fold) / 0.08) 0, + rgb(var(--rgb-blame-fold) / 0.08) 4px, transparent 4px, transparent 8px ); diff --git a/apps/desktop/src/renderer/src/styles/features/diff/comment-zone.scss b/apps/desktop/src/renderer/src/styles/features/diff/comment-zone.scss index 936c6223..00895308 100644 --- a/apps/desktop/src/renderer/src/styles/features/diff/comment-zone.scss +++ b/apps/desktop/src/renderer/src/styles/features/diff/comment-zone.scss @@ -74,7 +74,7 @@ .comment-zone-edit-btn:hover { border-color: $color-info; color: $color-info; - background: rgba($color-accent, 0.08); + background: rgb(var(--rgb-accent) / 0.08); } // 删除按钮主色用 danger,跟其它按钮拉开语义;disabled 时半透明 .comment-zone-delete-btn:hover:not(:disabled) { @@ -108,7 +108,7 @@ padding: $space-3 $space-4; font-size: $fs-sm; color: $color-danger; - background: rgba($color-danger, 0.10); + background: rgb(var(--rgb-danger) / 0.10); border-left: 3px solid $color-danger; border-radius: $radius-sm; word-break: break-word; @@ -223,7 +223,7 @@ background: $color-accent; border-radius: $radius-full; transform: translate(-50%, -50%); - box-shadow: 0 0 0 1px rgba($color-accent, 0.4); + box-shadow: 0 0 0 1px rgb(var(--rgb-accent) / 0.4); } } diff --git a/apps/desktop/src/renderer/src/styles/features/diff/draft-zone.scss b/apps/desktop/src/renderer/src/styles/features/diff/draft-zone.scss index 918d51d3..5f595c6c 100644 --- a/apps/desktop/src/renderer/src/styles/features/diff/draft-zone.scss +++ b/apps/desktop/src/renderer/src/styles/features/diff/draft-zone.scss @@ -24,7 +24,7 @@ // 同样防御 z-index:inner 内部按钮永远在最顶层 position: relative; z-index: 51; - background: rgba($color-accent, 0.12); // $color-accent fade + background: rgb(var(--rgb-accent) / 0.12); // $color-accent fade border-left: 3px solid $color-accent; padding: $space-3 $space-6 $space-4 $space-6; font-family: @@ -98,7 +98,7 @@ color: $color-info; } &.draft-zone-status-chip-posted { - background: rgba($color-approved, 0.18); + background: rgb(var(--rgb-approved) / 0.18); color: $color-approved; } &.draft-zone-status-chip-rejected { @@ -232,7 +232,7 @@ padding: $space-3 $space-4; font-size: $fs-sm; color: $color-danger; - background: rgba($color-danger, 0.10); + background: rgb(var(--rgb-danger) / 0.10); border-left: 3px solid $color-danger; border-radius: $radius-sm; word-break: break-word; @@ -270,7 +270,7 @@ font-size: 14px; font-weight: 700; line-height: 1; - background: rgba($color-accent, 0.18); + background: rgb(var(--rgb-accent) / 0.18); border-radius: $radius-sm; } @@ -282,14 +282,14 @@ // nav 跳转 reveal 后短暂高亮 (0.8s 脉冲),help 用户看清落到哪一行 .monaco-draft-highlight-flash { - background: rgba($color-warning, 0.25); + background: rgb(var(--rgb-warning) / 0.25); animation: draft-nav-flash 0.8s ease-out; } @keyframes draft-nav-flash { 0% { - background: rgba($color-warning, 0.5); + background: rgb(var(--rgb-warning) / 0.5); } 100% { - background: rgba($color-warning, 0.05); + background: rgb(var(--rgb-warning) / 0.05); } } diff --git a/apps/desktop/src/renderer/src/styles/features/diff/search.scss b/apps/desktop/src/renderer/src/styles/features/diff/search.scss index e0ccb15b..c9d8c3e6 100644 --- a/apps/desktop/src/renderer/src/styles/features/diff/search.scss +++ b/apps/desktop/src/renderer/src/styles/features/diff/search.scss @@ -80,7 +80,7 @@ padding: $space-3 $space-4; font-size: $fs-sm; color: $color-danger; - background: rgba($color-danger, 0.08); + background: rgb(var(--rgb-danger) / 0.08); border-bottom: 1px solid $border-muted; } diff --git a/apps/desktop/src/renderer/src/styles/features/diff/view.scss b/apps/desktop/src/renderer/src/styles/features/diff/view.scss index d3bcc5f5..53752a8d 100644 --- a/apps/desktop/src/renderer/src/styles/features/diff/view.scss +++ b/apps/desktop/src/renderer/src/styles/features/diff/view.scss @@ -178,16 +178,16 @@ align-items: center; gap: $space-5; padding: $space-3 $space-6; - background: rgba($color-danger, 0.08); - border-bottom: 1px solid rgba($color-danger, 0.35); + background: rgb(var(--rgb-danger) / 0.08); + border-bottom: 1px solid rgb(var(--rgb-danger) / 0.35); color: $text-primary; font-size: $fs-sm; flex-shrink: 0; &.backend-error-banner-auth, &.backend-error-banner-not-found { - background: rgba($git-modified, 0.1); - border-bottom-color: rgba($git-modified, 0.4); + background: rgb(var(--rgb-git-modified) / 0.1); + border-bottom-color: rgb(var(--rgb-git-modified) / 0.4); } } .backend-error-banner-icon { diff --git a/apps/desktop/src/renderer/src/styles/features/drafts-panel.scss b/apps/desktop/src/renderer/src/styles/features/drafts-panel.scss index bdf9d38b..fa2e3b4a 100644 --- a/apps/desktop/src/renderer/src/styles/features/drafts-panel.scss +++ b/apps/desktop/src/renderer/src/styles/features/drafts-panel.scss @@ -199,7 +199,7 @@ padding: $space-3 $space-4; font-size: $fs-sm; color: $color-danger; - background: rgba($color-danger, 0.10); + background: rgb(var(--rgb-danger) / 0.10); border-left: 3px solid $color-danger; border-radius: $radius-sm; word-break: break-word; diff --git a/apps/desktop/src/renderer/src/styles/features/pr/activity.scss b/apps/desktop/src/renderer/src/styles/features/pr/activity.scss index a3aa1fae..2020d1c7 100644 --- a/apps/desktop/src/renderer/src/styles/features/pr/activity.scss +++ b/apps/desktop/src/renderer/src/styles/features/pr/activity.scss @@ -105,7 +105,7 @@ font-weight: 600; } .pr-activity-chip-approved { - background: rgba($color-approved, 0.16); + background: rgb(var(--rgb-approved) / 0.16); color: $color-approved; } .pr-activity-chip-needsWork { diff --git a/apps/desktop/src/renderer/src/styles/features/pr/comments.scss b/apps/desktop/src/renderer/src/styles/features/pr/comments.scss index f8de7609..7cd8435a 100644 --- a/apps/desktop/src/renderer/src/styles/features/pr/comments.scss +++ b/apps/desktop/src/renderer/src/styles/features/pr/comments.scss @@ -107,7 +107,7 @@ // base 侧 (old) 用红调,head 侧 (new) 用绿调,跟 diff 视觉一致 &.pr-comment-anchor-old { - background: rgba($color-danger, 0.15); + background: rgb(var(--rgb-danger) / 0.15); color: $color-danger; } &.pr-comment-anchor-new { @@ -173,7 +173,7 @@ &:hover:not(:disabled) { border-color: $color-info; color: $color-info; - background: rgba($color-accent, 0.08); + background: rgb(var(--rgb-accent) / 0.08); } } // 删除按钮:跟回复按钮同尺寸,主色用 danger 让用户一眼识别为破坏性操作。 @@ -205,7 +205,7 @@ padding: $space-3 $space-4; font-size: $fs-sm; color: $color-danger; - background: rgba($color-danger, 0.1); + background: rgb(var(--rgb-danger) / 0.1); border-left: 3px solid $color-danger; border-radius: $radius-sm; word-break: break-word; @@ -345,7 +345,7 @@ // Monaco decoration:锚定行整行底色 + 左侧色带 (margin gutter),跟 inline 锚点 // chip 颜色保持一组语义 (warning amber 区分于 added 绿 / removed 红) .comment-code-context-anchor-line { - background: rgba($color-warning, 0.18); + background: rgb(var(--rgb-warning) / 0.18); } .comment-code-context-anchor-gutter { background: $color-warning; diff --git a/apps/desktop/src/renderer/src/styles/features/pr/header-actions.scss b/apps/desktop/src/renderer/src/styles/features/pr/header-actions.scss index 9d7e2ded..451c4559 100644 --- a/apps/desktop/src/renderer/src/styles/features/pr/header-actions.scss +++ b/apps/desktop/src/renderer/src/styles/features/pr/header-actions.scss @@ -33,7 +33,7 @@ &:hover:not(:disabled) { // hover 给确定反馈:停闪 + 实心绿描边 + 浅绿填充 animation: none; - background: rgba($color-approved, 0.14); + background: rgb(var(--rgb-approved) / 0.14); border-color: $color-approved; } &:disabled { @@ -47,7 +47,7 @@ } 50% { border-color: $color-approved; - background: rgba($color-approved, 0.14); + background: rgb(var(--rgb-approved) / 0.14); } } // 降低动态偏好:不闪烁,保留绿描边以示可合并 @@ -75,7 +75,7 @@ &:hover { // 用极浅的主色填充 (~10% 透明);border 同时加深一档强化可点感 - background: rgba($color-accent, 0.12); + background: rgb(var(--rgb-accent) / 0.12); } } } diff --git a/apps/desktop/src/renderer/src/styles/features/pr/publish-review.scss b/apps/desktop/src/renderer/src/styles/features/pr/publish-review.scss index c005e9cb..4053f2cd 100644 --- a/apps/desktop/src/renderer/src/styles/features/pr/publish-review.scss +++ b/apps/desktop/src/renderer/src/styles/features/pr/publish-review.scss @@ -94,7 +94,7 @@ &.status-edited { color: $color-info; - background: rgba($color-accent, 0.15); + background: rgb(var(--rgb-accent) / 0.15); } } .publish-review-item-body { diff --git a/apps/desktop/src/renderer/src/styles/features/settings/forms.scss b/apps/desktop/src/renderer/src/styles/features/settings/forms.scss index dc34ffc4..8a9f72ba 100644 --- a/apps/desktop/src/renderer/src/styles/features/settings/forms.scss +++ b/apps/desktop/src/renderer/src/styles/features/settings/forms.scss @@ -33,8 +33,9 @@ .settings-nav-item { display: flex; align-items: center; - gap: $space-3; - padding: $space-3 $space-4; + // 图标与文案间距放宽:原 $space-3 视觉上偏挤、偏左,拉到 $space-5 让二者更舒展 + gap: $space-5; + padding: $space-3 $space-5; border: none; border-radius: $radius-md; background: transparent; @@ -68,6 +69,11 @@ overflow-y: auto; padding: $space-8; + // 设置页配置项上下间距放宽一档(比通用 modal 的 $space-8 更舒展),避免堆叠拥挤 + .modal-section { + margin-bottom: 20px; + } + // 分区内末个 section 去掉多余底部留白 .modal-section:last-child { margin-bottom: 0; @@ -79,6 +85,15 @@ flex: 0 0 auto; width: 180px; } +// 整行铺满的输入(编辑器字体:自由输入、可能较长的逗号分隔列表,单独成行铺满、不靠右压缩) +.settings-input.settings-input-block { + flex: none; + width: 100%; +} +// 单独成行的字段:标题在上、控件在下;收紧标题与控件间距 +.settings-field-stacked h4 { + margin-bottom: $space-3; +} // 设置项启用状态 chip:复用 common chip 词汇 —— on=approved(绿)、off=neutral(灰) .settings-status-chip { @@ -272,7 +287,7 @@ select.settings-input { &:focus { border-color: $color-danger !important; - box-shadow: 0 0 0 1px rgba($color-danger, 0.3); + box-shadow: 0 0 0 1px rgb(var(--rgb-danger) / 0.3); } } .settings-field-error { diff --git a/apps/desktop/src/renderer/src/theme/index.ts b/apps/desktop/src/renderer/src/theme/index.ts new file mode 100644 index 00000000..628f75d0 --- /dev/null +++ b/apps/desktop/src/renderer/src/theme/index.ts @@ -0,0 +1,99 @@ +import { + matchThemePreference, + type ResolvedTheme, + type ThemePreference, +} from '@meebox/shared'; + +/** + * 渲染层主题运行时。 + * + * 主题偏好(system / light / dark)解析为实际视觉主题(light / dark),写到 `documentElement` + * 的 `data-theme`;配色经 CSS 自定义属性整体切换(默认 :root = 暗色,`[data-theme='light']` + * 覆盖为浅色,见 styles/_theme.scss)。 + * + * - 偏好经 IPC 异步到达(config.appearance.theme),启动时拿不到;localStorage 可同步读,故用它做 + * 首帧初始主题,避免浅色用户启动先闪一帧深色。App 拿到 config 后会 persist 回写,下次启动直接命中。 + * - 偏好为 'system' 时跟随 `prefers-color-scheme`,并由 watchSystemTheme 在 OS 切换时实时重解析。 + * - 默认偏好取 **dark**(与历史一致):localStorage 无记录、解析失败时回落深色。 + */ + +const THEME_STORAGE_KEY = 'meebox.theme'; +const DEFAULT_PREFERENCE: ThemePreference = 'dark'; + +/** OS 是否偏好深色('system' 偏好据此解析)。matchMedia 不可用时保守按深色。 */ +function systemPrefersDark(): boolean { + try { + return window.matchMedia('(prefers-color-scheme: dark)').matches; + } catch { + return true; + } +} + +/** 把主题偏好解析为实际视觉主题。 */ +export function resolveTheme(preference: ThemePreference): ResolvedTheme { + if (preference === 'system') return systemPrefersDark() ? 'dark' : 'light'; + return preference; +} + +/** 读 localStorage 缓存的偏好作首帧初始值;无记录 / 不可用时回落默认(dark)。 */ +export function readInitialThemePreference(): ThemePreference { + try { + return matchThemePreference(localStorage.getItem(THEME_STORAGE_KEY)) ?? DEFAULT_PREFERENCE; + } catch { + return DEFAULT_PREFERENCE; + } +} + +/** 持久化偏好到 localStorage,供下次启动同步读取作初始主题。 */ +export function persistThemePreference(preference: ThemePreference): void { + try { + localStorage.setItem(THEME_STORAGE_KEY, preference); + } catch { + // localStorage 不可用时忽略:仅影响下次启动的初始主题命中,不影响功能。 + } +} + +/** 把偏好解析后写到 documentElement.data-theme,触发 CSS 自定义属性整体切换。 */ +export function applyThemePreference(preference: ThemePreference): void { + document.documentElement.dataset.theme = resolveTheme(preference); +} + +/** + * 监听 OS 深 / 浅色变化。仅 'system' 偏好需要:OS 切换时实时重解析并重写 data-theme。 + * 返回取消订阅函数;非 'system' 偏好直接返回空 cleanup(无监听)。 + */ +export function watchSystemTheme(preference: ThemePreference): () => void { + if (preference !== 'system') return () => {}; + let mq: MediaQueryList; + try { + mq = window.matchMedia('(prefers-color-scheme: dark)'); + } catch { + return () => {}; + } + const onChange = (): void => applyThemePreference('system'); + mq.addEventListener('change', onChange); + return () => mq.removeEventListener('change', onChange); +} + +// 内置等宽字体兜底栈:用户自定义字体后置于其后,保证缺字时仍回落到合理 mono 字体。 +const MONO_FALLBACK = "'Cascadia Code', 'Consolas', ui-monospace, monospace"; + +/** 把用户配置的字体族解析为完整 font-family 串(追加兜底栈);空配置返回 undefined(用默认)。 */ +export function resolveEditorFontFamily(font: string): string | undefined { + const f = font.trim(); + return f ? `${f}, ${MONO_FALLBACK}` : undefined; +} + +/** + * 应用编辑器等宽字体到全应用:写 documentElement 的 `--editor-font-family` 自定义属性($font-mono 经 + * 它取值,覆盖 diff / 评论 / 代码块等所有等宽文本)。空配置时移除该属性,回落内置 mono 字体栈。 + * Monaco 编辑器内容字体另经其 fontFamily option 设置(见 DiffPane / InlineCodeContext)。 + */ +export function applyEditorFontFamily(font: string): void { + const resolved = resolveEditorFontFamily(font); + if (resolved) document.documentElement.style.setProperty('--editor-font-family', resolved); + else document.documentElement.style.removeProperty('--editor-font-family'); +} + +// 副作用:模块导入即按 localStorage 缓存定下首帧主题(在 React 渲染前),避免浅色用户启动闪深色。 +applyThemePreference(readInitialThemePreference()); diff --git a/packages/ipc/src/config.ts b/packages/ipc/src/config.ts index b8976a76..d76fcb7a 100644 --- a/packages/ipc/src/config.ts +++ b/packages/ipc/src/config.ts @@ -1,4 +1,11 @@ -import type { Config, PingResult, PlatformKind, SupportedLanguage } from '@meebox/shared'; +import type { + Config, + EditorTheme, + PingResult, + PlatformKind, + SupportedLanguage, + ThemePreference, +} from '@meebox/shared'; /** 配置操作域:读 / 写 config.yaml(含热生效与草稿暂存)及连接 / 代理试连。 */ export interface ConfigChannels { @@ -11,6 +18,19 @@ export interface ConfigChannels { * 与代理/连接同属热生效项,无需依赖设置页全局保存。 */ 'config:setLanguage': { request: { language: SupportedLanguage }; response: void }; + /** + * 写入 GUI 主题偏好到 config.yaml。主题为纯前端展示项:实际切换由 renderer 即时完成(写 + * documentElement data-theme),此通道仅持久化偏好,无主进程副作用。 + */ + 'config:setTheme': { request: { theme: ThemePreference }; response: void }; + /** + * 写入编辑器外观(Monaco 配色主题 + 等宽字体族)到 config.yaml。纯前端展示项:实际切换由 renderer + * 即时完成(Monaco theme 切换 + 字体 CSS 变量),此通道仅持久化偏好,无主进程副作用。 + */ + 'config:setEditorAppearance': { + request: { editor_theme: EditorTheme; editor_font_family: string; editor_font_size: number }; + response: void; + }; /** 写入 LLM Provider 配置到 config.yaml;下次 pragent:run 自动用新值 */ 'config:setLlm': { request: { llm: Config['llm'] }; response: void }; /** 写入 agent.dir 到 config.yaml;下次 pragent:run 立即生效 (现读规则) */ diff --git a/packages/shared/src/config.ts b/packages/shared/src/config.ts index 9268c484..955eef96 100644 --- a/packages/shared/src/config.ts +++ b/packages/shared/src/config.ts @@ -1,4 +1,10 @@ import { z } from 'zod'; +import { + EDITOR_FONT_SIZE_DEFAULT, + EDITOR_FONT_SIZE_MAX, + EDITOR_FONT_SIZE_MIN, + EDITOR_THEME_IDS, +} from './theme.js'; export const CloneSettingsSchema = z .object({ @@ -158,6 +164,35 @@ export const ConfigSchema = z.object({ * 非空则按显式选择。透传到容器 `CONFIG__RESPONSE_LANGUAGE`(经解析后的有效值)。 */ language: z.string().default(''), + /** + * 外观偏好(GUI 主题等纯前端展示项;主进程不消费)。预留分组,后续编辑器主题 / 字体等并入此处。 + */ + appearance: z + .object({ + /** + * GUI 主题偏好:'system' 跟随操作系统深 / 浅色,'light' / 'dark' 固定。**默认 'dark'** + * (与历史一致,升级不改变现有用户外观);解析与生效在 renderer(见 renderer/src/theme)。 + */ + theme: z.enum(['system', 'light', 'dark']).default('dark'), + /** + * 代码编辑器(Monaco)配色主题:'auto' 跟随 GUI 深 / 浅色(默认),其余为内置 / 第三方主题 id + * (见 @meebox/shared EDITOR_THEME_OPTIONS)。 + */ + editor_theme: z.enum(EDITOR_THEME_IDS).default('auto'), + /** + * 编辑器等宽字体族(CSS font-family,可逗号分隔多候选)。**默认空** = 用内置 mono 字体栈; + * 非空则覆盖编辑器与全应用等宽文本字体。 + */ + editor_font_family: z.string().default(''), + /** 编辑器字号(px)。限合理范围(见 EDITOR_FONT_SIZE_MIN/MAX),默认 14;按平台再做微调。 */ + editor_font_size: z + .number() + .int() + .min(EDITOR_FONT_SIZE_MIN) + .max(EDITOR_FONT_SIZE_MAX) + .default(EDITOR_FONT_SIZE_DEFAULT), + }) + .default({}), workspace: z .object({ repos_dir: z.string().default('~/.code-meeseeks/repos'), diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 498123e5..91f4350e 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -8,4 +8,5 @@ export * from './platform.js'; export * from './poller-contract.js'; export * from './pr-agent-status.js'; export * from './sync-progress.js'; +export * from './theme.js'; export * from './tool-registry.js'; diff --git a/packages/shared/src/theme.ts b/packages/shared/src/theme.ts new file mode 100644 index 00000000..e0748861 --- /dev/null +++ b/packages/shared/src/theme.ts @@ -0,0 +1,75 @@ +/** + * GUI 主题偏好(main / renderer 共用类型)。 + * + * - `'system'`:跟随操作系统深色 / 浅色偏好(renderer 经 `prefers-color-scheme` 解析,OS 切换实时跟随)。 + * - `'light'` / `'dark'`:固定浅色 / 深色,忽略 OS。 + * + * 实际生效的视觉主题(深 / 浅)由 renderer 把偏好解析后写到 `documentElement` 的 `data-theme`, + * 配色经 CSS 自定义属性整体切换(见 styles/_theme.scss)。主题为纯前端展示项,主进程不消费。 + */ +export const THEME_PREFERENCES = ['system', 'light', 'dark'] as const; +export type ThemePreference = (typeof THEME_PREFERENCES)[number]; + +/** 解析后的实际视觉主题(写入 data-theme 的值)。 */ +export type ResolvedTheme = 'light' | 'dark'; + +/** 把任意串规整为受支持的主题偏好,无法识别返回 null。 */ +export function matchThemePreference(value: string | null | undefined): ThemePreference | null { + return (THEME_PREFERENCES as readonly string[]).includes(value ?? '') + ? (value as ThemePreference) + : null; +} + +/** + * 代码编辑器(Monaco)配色主题选项。`id` 为生效的 Monaco 主题名,`label` 为展示名。 + * - `'auto'`:特殊值,跟随 GUI 主题(浅色用 `vs`、深色用 `vs-dark`),默认。 + * - `vs` / `vs-dark` / `hc-light` / `hc-black`:Monaco 内置主题。 + * - 其余为内置注册的第三方主题(见 renderer monaco-setup,取色自 monaco-themes)。 + * + * **label 不做 i18n**:主题为专有名(GitHub Dark / Monokai…),与语言 endonym 同理,各 UI 语言下 + * 展示一致、不翻译。**例外**:`'auto'` 非具体主题、而是「跟随应用」模式,其展示文案走 i18n + * (见 settings.editorThemeOptionAuto),本 label 仅作兜底。 + */ +export interface EditorThemeOption { + id: string; + label: string; +} + +export const EDITOR_THEME_OPTIONS = [ + { id: 'auto', label: 'Auto' }, + { id: 'dark-2026', label: 'Dark 2026' }, + { id: 'light-2026', label: 'Light 2026' }, + // Monaco 内置 vs / vs-dark 作为 Modern 默认(无需另引 VS Code Dark/Light Modern)。 + { id: 'vs-dark', label: 'Dark Modern' }, + { id: 'vs', label: 'Light Modern' }, + { id: 'hc-black', label: 'High Contrast Dark' }, + { id: 'hc-light', label: 'High Contrast Light' }, + { id: 'github-light', label: 'GitHub Light' }, + { id: 'github-dark', label: 'GitHub Dark' }, + { id: 'monokai', label: 'Monokai' }, + { id: 'dracula', label: 'Dracula' }, + { id: 'nord', label: 'Nord' }, + { id: 'night-owl', label: 'Night Owl' }, + { id: 'tomorrow', label: 'Tomorrow' }, + { id: 'tomorrow-night', label: 'Tomorrow Night' }, + { id: 'solarized-light', label: 'Solarized Light' }, + { id: 'solarized-dark', label: 'Solarized Dark' }, + { id: 'cobalt2', label: 'Cobalt2' }, + { id: 'oceanic-next', label: 'Oceanic Next' }, +] as const satisfies readonly EditorThemeOption[]; + +export type EditorTheme = (typeof EDITOR_THEME_OPTIONS)[number]['id']; + +/** 受支持的编辑器主题 id 元组(供 zod enum 校验用)。 */ +export const EDITOR_THEME_IDS = EDITOR_THEME_OPTIONS.map((o) => o.id) as [ + EditorTheme, + ...EditorTheme[], +]; + +/** 编辑器字号合理范围(px)与默认值。下限保证可读、上限避免过大破坏布局;默认对齐历史 14px。 */ +export const EDITOR_FONT_SIZE_MIN = 8; +export const EDITOR_FONT_SIZE_MAX = 32; +export const EDITOR_FONT_SIZE_DEFAULT = 14; + +/** 设置页字号下拉的预设档位(仍受上面 min/max 约束;config 手改可取范围内任意整数)。 */ +export const EDITOR_FONT_SIZE_PRESETS = [10, 11, 12, 13, 14, 15, 16, 18, 20, 24] as const;