@nonamelego/dsh-catppuccin 0.6.2-beta.2 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["Segmented","useSyncExternalStore","useState","useRef","css","useState","useRef","useSyncExternalStore","useState","useSyncExternalStore","useRef"],"sources":["../src/client/CatppuccinRow.tsx","../src/client/glass/glass-seams.ts","../src/client/glass/glass-css.gen.ts","../src/state.ts","../src/client/glass/glass-layer.ts","../src/client/glass/glass-row.tsx","../src/client/LinksRow.tsx","../src/client/UpdateRow.tsx","../src/client/detail-card.tsx","../src/client/locales.ts","../src/client/palettes.ts","../src/client/shiki-tokens.ts","../src/update-check.ts","../src/registration-tolerance.ts","../src/client/state-sync.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Catppuccin settings row — one General-section preference row listing the\n * four flavour themes plus a \"follow system\" (off) choice. Selecting a\n * flavour calls the injected `select`, which switches the official\n * ThemeRuntime and persists the choice. The row subscribes to `theme/change`\n * so the highlighted flavour tracks the live preference.\n *\n * Beyond the flavour pick the row carries:\n * - per-flavour localized subtitles (item DD) under the button labels;\n * - the shiki style pick (item M, `default` / `italic-comments`);\n * - a collapsible power-user token-override editor (item K);\n * - a \"?\" help affordance (item J) — no framework tooltip API exists in\n * dsh-client-ui-slots yet, so the help text rides the native `title`\n * attribute plus an accessible name.\n */\nimport { useRef, useState, useSyncExternalStore } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { FlavorChoice } from './index.ts'\nimport type { ShikiStyle } from '../state.ts'\nimport type { CatppuccinKey } from './locales.ts'\n\n/** One flavour button shown by the row. */\nexport interface CatppuccinFlavorButton {\n /** Theme id registered into ThemeRuntime. */\n id: string\n /** Display label. */\n label: string\n /** Accent colour for the swatch. */\n accent: string\n}\n\n/** Injected business face of the row (assembled in apply). */\nexport interface CatppuccinRowInjected {\n /** The four flavours, in display order. */\n themes: readonly CatppuccinFlavorButton[]\n /** Current choice (`off` when a Catppuccin theme is not active). */\n current: () => FlavorChoice\n /** Subscribe to theme preference changes. Returns the disposer. */\n subscribe: (listener: () => void) => () => void\n /** Switch the theme and persist the choice (`off` reverts to system). */\n select: (choice: FlavorChoice) => void | Promise<void>\n /** Current user token overrides (item K). */\n overrides: () => Record<string, string>\n /** Replace the whole override map (persists + re-registers the theme). */\n setOverrides: (overrides: Record<string, string>) => void\n /** Current shiki style (item M). */\n shikiStyle: () => ShikiStyle\n /** Set the shiki style (persists + re-registers the theme). */\n setShikiStyle: (style: ShikiStyle) => void\n /** Subscribe to preference (overrides / shiki style) changes. */\n subscribePrefs: (listener: () => void) => () => void\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type CatppuccinRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'> & CatppuccinRowInjected\n\n/** 普通按钮行内样式。 */\nconst buttonBase: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 12px',\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l1)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary)',\n cursor: 'pointer',\n font: 'inherit',\n}\n\n/** 选中态按钮行内样式。 */\nconst buttonActive: React.CSSProperties = {\n ...buttonBase,\n border: '1px solid var(--dsw-alias-border-l3)',\n background: 'var(--dsw-alias-interactive-bg-active)',\n}\n\nconst inputBase: React.CSSProperties = {\n background: 'var(--dsw-alias-bg-layer-2)',\n border: '1px solid var(--dsw-alias-border-l1)',\n borderRadius: 6,\n padding: '4px 8px',\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 12,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n}\n\n/**\n * A \"?\" help affordance: an accessible button that carries the full help\n * text in the native `title` tooltip. No visual styling beyond the token\n * palette — the affordance follows the row's label colour.\n */\nfunction HelpIcon({ label, help }: { label: string; help: string }): React.JSX.Element {\n return (\n <span\n role=\"img\"\n aria-label={label}\n title={help}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n cursor: 'help',\n userSelect: 'none',\n marginLeft: 6,\n flex: 'none',\n }}\n >\n ?\n </span>\n )\n}\n\n/** The localised subtitle of one flavour button (`flavor.<id>.subtitle`);\n * null when the active locale carries no such key. */\nfunction subtitleText(buttonId: string, t: (key: CatppuccinKey) => string): string | null {\n const flavorId = buttonId.replace('catppuccin-', '')\n if (flavorId === buttonId) return null\n const key = `flavor.${flavorId}.subtitle` as CatppuccinKey\n const text = t(key)\n return text === key ? null : text\n}\n\n/** One two-sided segmented pick using the row's token colours. */\nfunction Segmented<T extends string>(props: {\n label: string\n value: T\n options: readonly { id: T; label: string }[]\n onSelect: (value: T) => void\n}): React.JSX.Element {\n const { label, value, options, onSelect } = props\n return (\n <div style={{ display: 'inline-flex', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, overflow: 'hidden' }} role=\"group\" aria-label={label}>\n {options.map((option, index) => (\n <button\n key={option.id}\n type=\"button\"\n aria-pressed={option.id === value}\n onClick={() => { onSelect(option.id) }}\n style={{\n height: 26,\n padding: '0 12px',\n border: 'none',\n borderLeft: index > 0 ? '1px solid var(--dsw-alias-border-l2)' : undefined,\n background: option.id === value ? 'var(--dsw-alias-state-business-tertiary)' : 'transparent',\n color: option.id === value ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-label-secondary)',\n fontSize: 12,\n lineHeight: '18px',\n cursor: 'pointer',\n }}\n >\n {option.label}\n </button>\n ))}\n </div>\n )\n}\n\n/**\n * Render the Catppuccin row: title, one swatch button per flavour, and a\n * follow-system button. The active flavour is highlighted; clicking a flavour\n * applies it immediately (live, no restart) and persists the choice.\n * @param props - composed slot props.\n * @returns the row element tree.\n */\nexport function CatppuccinRow({\n t,\n themes,\n current,\n subscribe,\n select,\n overrides,\n setOverrides,\n shikiStyle,\n setShikiStyle,\n subscribePrefs,\n}: CatppuccinRowProps): React.JSX.Element {\n const choice = useSyncExternalStore(subscribe, current)\n const overrideMap = useSyncExternalStore(subscribePrefs, overrides)\n const style = useSyncExternalStore(subscribePrefs, shikiStyle)\n const [overridesOpen, setOverridesOpen] = useState(false)\n // Unsaved editor rows: key+value inputs that only enter the override map\n // once both fields hold a value (power users type tokens, so the commit is\n // live — nothing to \"save\").\n //\n // `id` is a stable React key, NOT the array index (audit F5): the fields are\n // uncontrolled, so an index key made React reuse the deleted row's DOM node\n // for the next row after a delete — the input kept showing the removed row's\n // text while the state held the surviving row's value.\n const [draftRows, setDraftRows] = useState<Array<{ id: number; key: string; value: string }>>([])\n const nextDraftId = useRef(0)\n\n // Only `--`-prefixed keys are persistable (`sanitizeOverrides` drops the\n // rest on every read — localStorage and the settings document share one\n // shape), so an incomplete key stays a draft row instead of being committed\n // and silently dropped one read later.\n const isTokenKey = (key: string): boolean => key.trim().startsWith('--')\n\n /** Commit a draft row on blur. If both fields are valid, promote to persisted;\n * otherwise keep in draft state. Item XX: changed from onChange to onBlur so\n * the row stays stable while typing—typing the first character of the value\n * previously made the draft immediately promote and unmount the input mid-edit. */\n const commitDraftKey = (index: number, key: string): void => {\n const row = draftRows[index]\n if (isTokenKey(key) && row.value.trim() !== '') {\n setOverrides({ ...overrideMap, [key.trim()]: row.value })\n setDraftRows(draftRows.filter((_, i) => i !== index))\n } else {\n setDraftRows(draftRows.map((r, i) => (i === index ? { ...r, key } : r)))\n }\n }\n\n const commitDraftValue = (index: number, value: string): void => {\n const row = draftRows[index]\n if (isTokenKey(row.key) && value.trim() !== '') {\n setOverrides({ ...overrideMap, [row.key.trim()]: value })\n setDraftRows(draftRows.filter((_, i) => i !== index))\n } else {\n setDraftRows(draftRows.map((r, i) => (i === index ? { ...r, value } : r)))\n }\n }\n\n /** Rename (or, with an empty/invalid key, delete) a persisted override. The\n * key input is uncontrolled and commits on blur: writing on every keystroke\n * repersisted the entry under each intermediate key, and an intermediate\n * key that is not a `--` token made the row delete itself mid-typing. */\n const commitPersistedKey = (oldKey: string, newKey: string): void => {\n if (newKey === oldKey) return\n const next = { ...overrideMap }\n delete next[oldKey]\n if (isTokenKey(newKey)) next[newKey.trim()] = overrideMap[oldKey]\n setOverrides(next)\n }\n\n /** Set (or, with an empty value, delete) a persisted override's value.\n *\n * Item TT: the value input is uncontrolled and commits on blur, symmetric\n * with the key input. Per-keystroke commits meant `value.trim() === ''`\n * deleted the entry while the caret was still in the field, so the row\n * (input included) unmounted mid-typing — and every keystroke additionally\n * re-registered the whole theme. Trade-off, accepted deliberately: no more\n * \"recolour as I type\" preview (intermediate values like `#89b4` are invalid\n * CSS anyway, so that preview was only ever complete on paste), and an edit\n * that never loses focus (dialog closed with Esc) is not committed.\n *\n * Known trade-off: an uncontrolled input keeps its text when the persisted\n * value changes from another tab/settings write; the row re-syncs on reopen. */\n const commitPersistedValue = (key: string, value: string): void => {\n if (value === overrideMap[key]) return\n const next = { ...overrideMap }\n if (value.trim() === '') delete next[key]\n else next[key] = value\n setOverrides(next)\n }\n\n const removePersisted = (key: string): void => {\n const next = { ...overrideMap }\n delete next[key]\n setOverrides(next)\n }\n\n return (\n <div style={{ borderBottom: '1px solid var(--dsw-alias-border-l2)', display: 'flex', flexDirection: 'column', gap: '10px', padding: '16px 0' }}>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 14, lineHeight: '22px', display: 'flex', alignItems: 'center' }}>\n {t('row.title')}\n <HelpIcon label={t('row.helpLabel')} help={t('row.help')} />\n </div>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.description')}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>\n {themes.map((flavor) => {\n const selected = choice === flavor.id\n const subtitle = subtitleText(flavor.id, t)\n return (\n <button\n key={flavor.id}\n type=\"button\"\n aria-pressed={selected}\n onClick={() => void select(flavor.id)}\n style={{\n ...(selected ? buttonActive : buttonBase),\n flexDirection: subtitle !== null ? 'column' : 'row',\n alignItems: subtitle !== null ? 'flex-start' : 'center',\n gap: subtitle !== null ? 2 : 6,\n padding: subtitle !== null ? '5px 12px' : '6px 12px',\n }}\n >\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n <span aria-hidden=\"true\" style={{ width: 12, height: 12, borderRadius: 3, background: flavor.accent, flex: 'none' }} />\n {flavor.label}\n </span>\n {subtitle !== null && (\n <span style={{ fontSize: 10, lineHeight: '14px', color: 'var(--dsw-alias-label-tertiary)' }}>\n {subtitle}\n </span>\n )}\n </button>\n )\n })}\n <button\n key=\"off\"\n type=\"button\"\n aria-pressed={choice === 'off'}\n onClick={() => void select('off')}\n style={choice === 'off' ? buttonActive : buttonBase}\n >\n {t('row.off')}\n </button>\n </div>\n\n {/* Shiki style pick (item M). */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.shikiStyle')}\n </span>\n <Segmented\n label={t('row.shikiStyle')}\n value={style}\n options={[\n { id: 'default' as const, label: t('row.shikiDefault') },\n { id: 'italic-comments' as const, label: t('row.shikiItalicComments') },\n ]}\n onSelect={setShikiStyle}\n />\n </div>\n\n {/* Power-user token overrides (item K). */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n <button\n type=\"button\"\n aria-expanded={overridesOpen}\n onClick={() => { setOverridesOpen(!overridesOpen) }}\n style={{ ...buttonBase, alignSelf: 'flex-start', fontSize: 12, padding: '4px 10px' }}\n >\n {overridesOpen ? `▾` : `▸`} {t('row.overrides')} ({Object.keys(overrideMap).length})\n </button>\n {overridesOpen && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.overridesHint')}\n </div>\n {Object.keys(overrideMap).length === 0 && draftRows.length === 0 && (\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.overridesEmpty')}\n </div>\n )}\n {Object.entries(overrideMap).map(([key, value]) => (\n <div key={key} style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignItems: 'center' }}>\n <input\n type=\"text\"\n aria-label={t('row.overridesKey')}\n defaultValue={key}\n onBlur={(e) => { commitPersistedKey(key, e.target.value) }}\n placeholder=\"--dsw-static-blue-500\"\n style={{ flex: '1 1 220px', ...inputBase }}\n />\n <input\n type=\"text\"\n aria-label={t('row.overridesValue')}\n defaultValue={value}\n onBlur={(e) => { commitPersistedValue(key, e.target.value) }}\n placeholder=\"#89b4fa\"\n style={{ flex: '1 1 140px', ...inputBase }}\n />\n <button\n type=\"button\"\n aria-label={t('row.overridesRemove')}\n onClick={() => { removePersisted(key) }}\n style={{ ...buttonBase, padding: '4px 8px', fontSize: 12 }}\n >\n ✕\n </button>\n </div>\n ))}\n {draftRows.map((row, index) => (\n <div key={row.id} style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignItems: 'center' }}>\n <input\n type=\"text\"\n aria-label={t('row.overridesKey')}\n defaultValue={row.key}\n onBlur={(e) => { commitDraftKey(index, e.target.value) }}\n placeholder=\"--dsw-static-blue-500\"\n style={{ flex: '1 1 220px', ...inputBase }}\n />\n <input\n type=\"text\"\n aria-label={t('row.overridesValue')}\n defaultValue={row.value}\n onBlur={(e) => { commitDraftValue(index, e.target.value) }}\n placeholder=\"#89b4fa\"\n style={{ flex: '1 1 140px', ...inputBase }}\n />\n <button\n type=\"button\"\n aria-label={t('row.overridesRemove')}\n onClick={() => { setDraftRows(draftRows.filter((_, i) => i !== index)) }}\n style={{ ...buttonBase, padding: '4px 8px', fontSize: 12 }}\n >\n ✕\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n onClick={() => {\n nextDraftId.current += 1\n setDraftRows([...draftRows, { id: nextDraftId.current, key: '', value: '' }])\n }}\n style={{ ...buttonBase, alignSelf: 'flex-start', fontSize: 12, padding: '4px 10px' }}\n >\n + {t('row.overridesAdd')}\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}","/**\n * Runtime seam stamper for the Catppuccin glass layer.\n *\n * The glass stylesheet keys off stable data-* hooks (`data-dsh-glass-frame`,\n * `data-dsh-glass-trajectory`, `data-dsh-glass-stats`, …) that are NOT part\n * of the stock DSH markup, so this module stamps them onto the matching\n * elements at runtime — the stylesheet works with zero base edits. Each\n * selector uses only stable attributes already present in the stock UI\n * (`data-composer-card`, `data-conversation-composer-overlay`, `data-slot`,\n * ARIA roles) or lightningcss-preserved class-name substrings.\n *\n * Stamps are idempotent and inert without the `data-dsh-glass` root attribute\n * (the whole stylesheet is gated on it), so they are simply left in place when\n * the layer flips off — \"off\" still renders the exact stock UI.\n */\n\ninterface Seam {\n /** Attribute to stamp (bare name; value is always ''). */\n readonly attribute: string\n /** CSS selector for the element(s) to stamp. */\n readonly selector: string\n /** Stamp only the first (topmost) match, not every descendant match. */\n readonly first?: boolean\n}\n\nconst SEAMS: readonly Seam[] = [\n // The layout frame: the sidebar column's direct parent.\n { attribute: 'data-dsh-glass-frame', selector: ':has(> [class*=\"sidebarCol\"])' },\n // The sidebar content root (topmost `root` under the column — settings\n // internals also carry a `root` class but sit deeper, so first match wins).\n { attribute: 'data-dsh-glass-sidebar-root', selector: '[class*=\"sidebarCol\"] [class*=\"root\"]', first: true },\n // New-session button (a raised-surface seam).\n { attribute: 'data-dsh-glass-surface', selector: 'button[class*=\"newSession\"]' },\n // Trajectory view (the composer-overlay view).\n { attribute: 'data-dsh-glass-trajectory', selector: '[data-conversation-composer-overlay]' },\n // Right panel (会话右侧栏 / 详情栏). The column was renamed upstream —\n // `detailsCol` through 0.1.2-rc.1, `rightbarCol` from 0.1.5-rc.2 on\n // (ui-layout/src/client/AppFrame.module.css) — and the old `[class*=\"root\"]`\n // descendant had no stable target: ui-sidebar-right ships `.session` /\n // `.panel`, while the tab views it hosts DO carry a `root` class\n // (ui-sidebar-files / browser / terminal), so the stamp landed on whichever\n // content view happened to be open — and on none of them for the document\n // preview. The panel itself carries the stable `data-sidebar-right-panel`\n // attribute (SidebarRight.tsx), which is what the stylesheet actually wants\n // (it makes the panel background transparent so the ground shows through).\n { attribute: 'data-dsh-glass-details', selector: '[class*=\"rightbarCol\"] [data-sidebar-right-panel], [class*=\"detailsCol\"] [class*=\"root\"]', first: true },\n // Composer bar root: the composer card's direct parent.\n { attribute: 'data-dsh-glass-inputbar', selector: ':has(> [data-composer-card])' },\n // Composer attach \"+\" button (ui-conversation InputBar.tsx -> css.add).\n { attribute: 'data-dsh-glass-add', selector: '[data-composer-card] [class*=\"add\"]' },\n // Session stats line under the composer (composer.dock slot). The slot renders\n // the entry with no wrapper of its own, so StatsPills' own root is both the\n // slot's direct child and a `root`-classed div (`<div className={css.root}\n // data-composer-stats>` in ui-chat/src/client/chat/StatsPills.tsx, present in\n // 0.1.5-rc.2 and 0.1.7 alike). Picking the row by position (`> *`) keeps\n // working if that class name ever changes; both parts resolve to the same\n // element today, and stamping is idempotent.\n { attribute: 'data-dsh-glass-stats', selector: '[data-slot=\"conversation.composer.dock\"] > *, [data-slot=\"conversation.composer.dock\"] [class*=\"root\"]' },\n // Settings dialog: a fixed overlay portalled inside the sidebar column\n // (the wrapper around the dialog panel in dsh-client-ui-settings-general).\n // Its rows/pickers paint themselves with the opaque raised-surface tokens,\n // so the stylesheet needs one hook on the dialog to re-point them at glass\n // mixes. Matched by the panel's accessible attributes, not its CSS-module\n // class: the host class name is a build hash (`VOzbGW_overlay`) that changes\n // whenever the host stylesheet does, and a stale selector would silently\n // drop the settings dialog back to opaque cards.\n { attribute: 'data-dsh-glass-settings', selector: ':has(> [role=\"dialog\"][aria-modal=\"true\"])' },\n]\n\nfunction stamp(seam: Seam): void {\n if (seam.first) {\n const el = document.querySelector(seam.selector)\n if (el !== null && !el.hasAttribute(seam.attribute)) el.setAttribute(seam.attribute, '')\n return\n }\n for (const el of document.querySelectorAll(seam.selector)) {\n if (!el.hasAttribute(seam.attribute)) el.setAttribute(seam.attribute, '')\n }\n}\n\nfunction stampAll(): void {\n for (const seam of SEAMS) stamp(seam)\n}\n\n/**\n * Stamp the seams once, then keep them stamped as React remounts nodes.\n *\n * The observer callback is debounced through `requestAnimationFrame` (item\n * N): DSH chat streaming mutates the DOM per token, and re-stamping on\n * every single mutation would re-run every selector per token. One frame\n * merges all mutations into one `stampAll()` — a streamed burst of N\n * mutations costs 1 stamp pass, and a frame with no mutations costs\n * nothing (the dirty flag skips the no-op stamp). Stamping stays idempotent\n * and cheap: `stamp()` only sets attributes that are missing.\n *\n * @returns a disposer that disconnects the observer and cancels any\n * pending frame.\n */\nexport function startGlassSeamStamper(): () => void {\n stampAll()\n let frame: number | undefined\n let dirty = false\n let disposed = false\n const stampFrame = (): void => {\n frame = undefined\n if (!dirty) return\n dirty = false\n stampAll()\n }\n const schedule = (): void => {\n // A MutationObserver callback can already be queued as a microtask when the\n // disposer runs — disconnect() does not recall it. Without this guard that\n // callback re-arms a frame and stamps *after* dispose (full-suite timing\n // exposes it; single-file runs usually win the race).\n if (disposed) return\n dirty = true\n if (frame !== undefined) return\n frame = requestAnimationFrame(stampFrame)\n }\n const observer = new MutationObserver(schedule)\n observer.observe(document.documentElement, { childList: true, subtree: true })\n return () => {\n disposed = true\n observer.disconnect()\n if (frame !== undefined) cancelAnimationFrame(frame)\n frame = undefined\n dirty = false\n }\n}\n","/**\n * AUTO-GENERATED by scripts/gen-glass-css.mjs — do not edit by hand.\n * The glass stylesheet text, generated from\n * src/client/glass/glass.module.css on every build. The browser half\n * mounts this text as a <style> tag only while the glass layer is on\n * (item II — lazy CSS), so editing the stylesheet means editing\n * glass.module.css and rebuilding.\n */\nexport const GLASS_CSS_TEXT: string = \"[data-dsh-glass] body{--dsh-glass-card:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(52% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-card-raised:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(64% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-card-hover:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(76% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-rim:color-mix(in srgb, var(--dsw-alias-label-primary) 18%, transparent);--dsh-glass-rim-soft:color-mix(in srgb, var(--dsw-alias-label-primary) 12%, transparent);--dsh-glass-rim-strong:color-mix(in srgb, var(--dsw-alias-label-primary) 30%, transparent);--dsh-glass-edge:inset 0 1px 0 #ffffff6b;--dsh-glass-drop:0 10px 32px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 38%, transparent);--dsh-glass-input-shadow:0 1px 2px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 65%, transparent), 0 8px 24px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 80%, transparent)}[data-dsh-glass] body[data-ds-dark-theme]{--dsh-glass-rim:color-mix(in srgb, var(--dsw-alias-label-primary) 24%, transparent);--dsh-glass-rim-soft:color-mix(in srgb, var(--dsw-alias-label-primary) 16%, transparent);--dsh-glass-rim-strong:color-mix(in srgb, var(--dsw-alias-label-primary) 30%, transparent);--dsh-glass-edge:inset 0 1px 0 #ffffff14;--dsh-glass-drop:0 10px 32px #02060e73;--dsh-glass-input-shadow:0 1px 2px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 65%, transparent), 0 8px 24px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 80%, transparent)}[data-dsh-glass] body{background:color-mix(in srgb, color-mix(in srgb, var(--dsw-alias-bg-base), #fff calc(var(--dsh-glass-brightness-white,0) * 100%)), #000 calc(var(--dsh-glass-brightness-black,0) * 100%))}[data-dsh-glass] [data-dsh-glass-frame],[data-dsh-glass] [data-phase],[data-dsh-glass] [data-dsh-glass-details]{background:0 0}[data-dsh-glass-float] [data-phase=active] header{z-index:8;position:relative}[data-dsh-glass-float] [class*=banner]{position:static}[data-dsh-glass-float] [data-phase=active] [data-conversation-scroll]{margin-top:-95px;padding-top:107px}[data-dsh-glass] [data-phase] [class*=composerSeat][class*=composerSeat]{background:0 0}[data-dsh-glass] [data-dsh-glass-fade]{z-index:7;pointer-events:none;backdrop-filter:blur(5px);background:#ffffff2e;height:13px;position:fixed;left:0;right:0}[data-dsh-glass] body[data-ds-dark-theme] [data-dsh-glass-fade]{background:#00000024}[data-dsh-glass] [data-dsh-glass-fade=top]{top:0;-webkit-mask-image:linear-gradient(#000 0%,#0000 100%);mask-image:linear-gradient(#000 0%,#0000 100%)}[data-dsh-glass][data-windows-titlebar] [data-dsh-glass-fade=top]{display:none}[data-dsh-glass] [data-dsh-glass-fade=bottom]{bottom:0;-webkit-mask-image:linear-gradient(#0000 0%,#000 100%);mask-image:linear-gradient(#0000 0%,#000 100%)}[data-dsh-glass-float] [data-menu-material=translucent],[data-dsh-glass-float] [role=menu]:not([data-menu-material]):not([data-menu-material] *),[data-dsh-glass-float] [role=dialog],[data-dsh-glass-float] [role=alert],[data-dsh-glass-float] [data-trigger-menu],[data-dsh-glass-float] [data-dsh-glass-surface]{border-radius:14px}[data-dsh-glass-float] [role=menuitem],[data-dsh-glass-float] [role=tooltip],[data-dsh-glass-float] [class*=pill]{border-radius:8px}[data-dsh-glass-float] button[class*=button]{border-radius:10px}[data-dsh-glass-float] [class*=iconButton],[data-dsh-glass-float] [class*=searchButton]{border-radius:8px}[data-dsh-glass-float] [class*=block]{--dsl-code-block-border-radius:14px;--dsl-diff-radius:14px;--dsl-read-radius:14px;--dsl-terminal-radius:14px;--dsl-web-radius:14px;--dsl-search-radius:14px;border-radius:14px}[data-dsh-glass-float] [data-dsh-glass-add]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-add]:hover:not(:disabled){background:var(--dsh-glass-card-hover)}[data-dsh-glass-float] [data-dsh-glass-surface]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-surface]:hover:not(:disabled){background:var(--dsh-glass-card-hover)}[data-dsh-glass-float] [data-conversation-scroll] [class*=bubble]{border:1px solid var(--dsh-glass-rim-soft);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(46% * var(--dsh-glass-frost,1)), transparent);border-radius:14px}[data-dsh-glass-float] [class*=card]{border-radius:14px}[data-dsh-glass] [data-dsh-glass-settings]{--dsh-glass-settings-raised:calc(38% + 38% * var(--dsh-glass-frost,1));--dsh-glass-settings-soft:calc(30% + 30% * var(--dsh-glass-frost,1));--dsw-alias-bg-module-platform:color-mix(in srgb, var(--dsw-static-neutral-bluish-800) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-3:color-mix(in srgb, var(--dsw-static-neutral-bluish-800) var(--dsh-glass-settings-soft), transparent);--dsw-alias-bg-layer-2:color-mix(in srgb, var(--dsw-static-neutral-bluish-850) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-1:color-mix(in srgb, var(--dsw-static-neutral-bluish-850) var(--dsh-glass-settings-soft), transparent);--dsw-specific-sidebar-nav-item-active:color-mix(in srgb, var(--dsw-static-neutral-bluish-750) var(--dsh-glass-settings-raised), transparent);--dsw-specific-sidebar-nav-item-hover:color-mix(in srgb, var(--dsw-static-neutral-bluish-850) var(--dsh-glass-settings-soft), transparent)}[data-dsh-glass] body:not([data-ds-dark-theme]) [data-dsh-glass-settings]{--dsw-alias-bg-module-platform:color-mix(in srgb, var(--dsw-static-neutral-bluish-60) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-3:color-mix(in srgb, var(--dsw-static-neutral-bluish-00) var(--dsh-glass-settings-soft), transparent);--dsw-alias-bg-layer-2:color-mix(in srgb, var(--dsw-static-neutral-bluish-00) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-1:color-mix(in srgb, var(--dsw-static-neutral-bluish-00) var(--dsh-glass-settings-soft), transparent);--dsw-specific-sidebar-nav-item-active:color-mix(in srgb, var(--dsw-static-neutral-bluish-100) var(--dsh-glass-settings-raised), transparent);--dsw-specific-sidebar-nav-item-hover:color-mix(in srgb, var(--dsw-static-neutral-bluish-75) var(--dsh-glass-settings-soft), transparent)}[data-dsh-glass-float] [data-phase] header{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:20px;margin:12px 16px 0;padding:10px 16px 8px}[data-dsh-glass-float] [data-phase] header:after{display:none}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] [data-phase] header{margin-left:28px}[data-dsh-glass-float] [class*=sidebarCol]{--dsw-specific-sidebar-fill:transparent;z-index:9;border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-drop);border-radius:20px;margin:12px;padding:10px 12px 14px;position:relative;overflow:hidden}[data-dsh-glass-float] [class*=sidebarCol]:before{content:\\\"\\\";border-radius:inherit;background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge);z-index:-1;pointer-events:none;transition:border-radius .15s var(--ds-ease-in-out);position:absolute;inset:0}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] [class*=sidebarCol]{transition:margin .15s var(--ds-ease-in-out), border-radius .15s var(--ds-ease-in-out);border-radius:16px;margin:12px -12px 12px 12px;padding:0}[data-dsh-glass-float] [data-dsh-glass-frame]:not([data-sidebar-collapsed]) [data-dsh-glass-sidebar-root]{width:100%!important}[data-dsh-glass-float] [data-dsh-glass-trajectory]{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);width:calc(100% - 32px);height:calc(100% - 20px);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);border-radius:20px;margin:8px 16px 12px;overflow:hidden}[data-dsh-glass-float] [data-dsh-glass-trajectory] [role=toolbar],[data-dsh-glass-float] [data-dsh-glass-trajectory] section[aria-label=Trajectory\\\\ timeline]{background:0 0}[data-dsh-glass-float] [data-composer-card],[data-dsh-glass-float] [data-composer-card]:after{border-radius:24px}[data-dsh-glass-float] [data-composer-card]{z-index:8;isolation:isolate;border:1px solid var(--dsh-glass-rim-strong);box-shadow:var(--dsh-glass-input-shadow);background:0 0;position:relative}[data-dsh-glass-float] [data-composer-card]:before{content:\\\"\\\";z-index:-1;border-radius:inherit;background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px));pointer-events:none;position:absolute;inset:0}[data-dsh-glass-float] [data-dsh-glass-inputbar]:not([class*=hero]):not(:has([data-dsh-glass-stats])){padding-bottom:12px}[data-dsh-glass-float] [role=treeitem][aria-selected=true]{background:color-mix(in srgb, var(--dsw-specific-sidebar-nav-item-active) 40%, transparent);box-shadow:0 0 14px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 12%, transparent)}[data-dsh-glass-float] button[class*=button]:hover:not(:disabled),[data-dsh-glass-float] [role=menuitem]:hover:not(:disabled){box-shadow:0 0 12px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 20%, transparent)}[data-dsh-glass-float] [data-menu-material=translucent]:not(:focus-visible){--dsw-menu-surface-fill:var(--dsh-glass-card-raised);--dsw-menu-backdrop-filter:blur(var(--dsh-glass-blur,14px));outline:1px solid var(--dsh-glass-rim-soft);outline-offset:-1px}[data-dsh-glass-float] [role=menu]:not([data-menu-material]):not([data-menu-material] *){background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim-soft);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-menu-material=translucent]:has([role=group]>[role=menuitemradio]){--dsw-menu-surface-fill:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 70%, transparent)}[data-dsh-glass-float] [data-menu-group]:has(>[role=menuitemradio])>[data-menu-group-heading]{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card-raised);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:999px;align-items:center;width:fit-content;margin:3px 0 5px 6px;padding:3px 10px;display:inline-flex}[data-dsh-glass-float] [role=dialog][aria-modal=true]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass] [data-conversation-scroll]{text-shadow:0 0 1px #ffffff80}[data-dsh-glass] body[data-ds-dark-theme] [data-conversation-scroll]{text-shadow:0 0 1px #0006}[data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot]{color:var(--dsw-alias-label-secondary)}[data-dsh-glass]{--dsh-glass-entry-scale:1}[data-dsh-glass-compat]{--dsh-glass-entry-scale:0}[data-dsh-glass] [data-phase=hero]{animation:dsh-glass-in calc(.32s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}[data-dsh-glass] [data-phase=active]{animation:dsh-glass-in calc(.3s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}[data-dsh-glass] [data-testid^=view-]{animation:dsh-glass-in calc(.26s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}[data-dsh-glass] [data-tool]{animation:dsh-glass-rise calc(.3s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out) both}[data-dsh-glass] [role=dialog]{animation:dsh-glass-dialog-in calc(.24s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}@keyframes dsh-glass-in{0%{opacity:0}}@keyframes dsh-glass-rise{0%{opacity:0;transform:translateY(6px)}}@keyframes dsh-glass-dialog-in{0%{opacity:0;transform:translateY(8px)scale(.985)}}[data-dsh-glass] :focus-visible{outline:2px solid color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 85%, transparent);outline-offset:1px}[data-dsh-glass] ::selection{background:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 35%, transparent)}[data-dsh-glass-compat] [role=menu]:not([data-menu-material]):not([data-menu-material] *),[data-dsh-glass-compat] [class*=popover],[data-dsh-glass-compat] [class*=dropdown]{backdrop-filter:blur(12px)}[data-dsh-glass-compat] [data-menu-material=translucent]:not(:focus-visible){--dsw-menu-surface-fill:var(--dsh-glass-card-raised);--dsw-menu-backdrop-filter:blur(12px);outline:1px solid var(--dsh-glass-rim);outline-offset:-1px}[data-dsh-glass-compat] [data-sidebar-right-panel][data-sidebar-right-open],[data-dsh-glass-compat] [data-sidebar-right-panel][data-sidebar-right-open] [class*=panel]{backdrop-filter:blur(12px)}[data-dsh-glass-compat] [role=menu]:not([data-menu-material]):not([data-menu-material] *),[data-dsh-glass-compat] [class*=popover],[data-dsh-glass-compat] [class*=dropdown]{background:var(--dsh-glass-card-raised)}[data-dsh-glass-compat] [data-composer-card]{isolation:isolate;backdrop-filter:none;background:0 0;position:relative}[data-dsh-glass-compat] [data-composer-card]:before{content:\\\"\\\";z-index:-1;border-radius:inherit;background:var(--dsh-glass-card-raised);backdrop-filter:blur(12px);pointer-events:none;position:absolute;inset:0}[data-dsh-glass-compat] [role=menu]:not([data-menu-material]):not([data-menu-material] *):not(:focus-visible),[data-dsh-glass-compat] [data-composer-card]:not(:focus-visible),[data-dsh-glass-compat] [class*=popover]:not(:focus-visible),[data-dsh-glass-compat] [class*=dropdown]:not(:focus-visible){outline:1px solid var(--dsh-glass-rim);outline-offset:-1px}[data-dsh-glass-compat] [role=dialog][aria-modal=true]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);backdrop-filter:blur(var(--dsh-glass-blur,12px))}@media (prefers-reduced-motion:reduce){[data-dsh-glass] [data-phase=hero],[data-dsh-glass] [data-phase=active],[data-dsh-glass] [data-testid^=view-],[data-dsh-glass] [data-tool],[data-dsh-glass] [role=dialog]{animation:none}}\"\n","/**\n * Durable Catppuccin state — the shared contract between the two halves.\n *\n * Why this exists: localStorage is scoped per origin, so it is the wrong place\n * for the ONLY copy of a preference. It is per-browser (two browsers on one\n * machine disagree), per-loopback-port (a second Desktop instance that lands\n * on the next free port gets a different origin — the official shell pins\n * `19387` and `anywhere-labs/dsh-desktop` starts at `43120` and increments on\n * a bind collision, both observed 2026-09-24), and it disappears whenever the\n * user clears site data. The durable copy lives in the official settings seam\n * under the DSH home, which is the machine-wide truth every browser and every\n * profile entry reads.\n *\n * (Historical note, corrected 2026-09-24: the 0.5.0 rationale claimed DSH\n * Desktop launched the profile with `--port 0`, \"a fresh random port every\n * launch\". That was already untrue when 0.5.0 shipped — the community shell\n * pinned a stable port on 2026-08-21, and the official shell passes an\n * explicit `--port 19387`. The design is unchanged and still justified by the\n * reasons above, but do not repeat the port-per-launch claim.)\n *\n * Since 0.5.0 the DURABLE copy lives in the official settings seam, which\n * persists under the DSH home exactly like the legacy\n * `$DSH_HOME/catppuccin-state.json` did — origin-independent, so it survives\n * the Desktop's per-launch port churn. The legacy file is kept as a\n * read-only migration source (`src/legacy-state.ts`) and rolled into the\n * settings document once (`src/index.ts`). Browser localStorage remains the\n * in-browser cache and cross-tab sync bus, and the Client's fallback when the\n * settings transport is unavailable. This module is dependency-free so both\n * bundles inline it (like `update-check.ts`).\n *\n * The seam itself is version-dependent (issue #15): DSH <= 0.1.6-alpha.2\n * serves a Client `ctx.settingsScope` bound to a namespace the plugin\n * registers itself (`CATPPUCCIN_SETTINGS_NS`), while >= 0.1.7-alpha.1 serves\n * `ctx.configForms` projecting the plugin's volatile `Config` form, keyed by\n * the PROFILE ENTRY ID (`CATPPUCCIN_ENTRY_ID`). Both are addressed from this\n * one contract (see `src/client/state-sync.ts`).\n */\nexport const STATE_VERSION = 1\n\n/** Release channels the update check knows about (a persisted preference;\n * `selectNewest` in `update-check.ts` consumes it). */\nexport type UpdateChannel = 'latest' | 'beta'\n\n/** Shiki syntax-highlighting style variants (see `src/client/shiki-tokens.ts`). */\nexport type ShikiStyle = 'default' | 'italic-comments'\n\n/** Legacy settings namespace (DSH <= 0.1.6-alpha.2): the Host registers it\n * through `settings.installSection`, the Client binds it through\n * `ctx.settingsScope` (see `src/settings-catppuccin.ts`). */\nexport const CATPPUCCIN_SETTINGS_NS = 'catppuccin'\n\n/**\n * Profile entry id carrying the plugin (DSH >= 0.1.7-alpha.1): the settings\n * service projects our volatile `Config` into a form named by the ACTIVE\n * PROFILE ENTRY's id, so this constant is the new seam's namespace.\n *\n * It is a CONTRACT with `cordis.patch.yml`: the `insert` row whose `name` is\n * `@nonamelego/dsh-catppuccin` must keep `id: dsh-catppuccin`, because the\n * Client can only address the form by that id (asserted by\n * `tests/settings-seam.spec.ts`). A user who renames the entry loses the new\n * seam and degrades to localStorage-only — the legacy seam is unaffected,\n * since that namespace is registered by the plugin itself.\n */\nexport const CATPPUCCIN_ENTRY_ID = 'dsh-catppuccin'\n\n/** State file name under the DSH home (kept next to the Desktop-managed\n * `cordis.patch.yml` so it survives the Desktop's per-launch port churn). */\nexport const STATE_FILENAME = 'catppuccin-state.json'\n\n/**\n * Whether a raw settings view carries a user layer at all.\n *\n * The two seams answer this differently and the difference is load-bearing\n * (issue #15): the NEW form's `user` is the profile patch's `override`, which\n * `configEditor.configuration()` defaults to `{}` — so \"absent\" arrives as an\n * EMPTY OBJECT, and `!== undefined` would be true forever. The LEGACY\n * document omits the field entirely when the document holds no such section,\n * so the old `!== undefined` test stays correct there. Callers must use the\n * predicate their channel defines (see `src/client/state-sync.ts`).\n * @param user - a snapshot's raw user layer.\n * @returns whether it holds at least one entry.\n */\nexport function hasUserLayerSection(user: unknown): boolean {\n return typeof user === 'object' && user !== null && !Array.isArray(user) && Object.keys(user).length > 0\n}\n\n/** The four registered Catppuccin theme ids. MUST stay in sync with the\n * `themeId` of `CATPPUCCIN_FLAVORS` in `src/client/palettes.ts` — guarded by\n * `tests/state.spec.ts` — because the persisted flavour value IS the theme id. */\nexport const CATPPUCCIN_THEME_IDS = [\n 'catppuccin-latte',\n 'catppuccin-frappe',\n 'catppuccin-macchiato',\n 'catppuccin-mocha',\n] as const\n\n/** A persisted flavour choice: one registered theme id or `off` (fall back to\n * the official theme). */\nexport type FlavorValue = (typeof CATPPUCCIN_THEME_IDS)[number] | 'off'\n\n/** Durable glass-layer settings (no derived `dark` field — that resolves at\n * runtime from the active theme). */\nexport interface GlassState {\n /** Layer enable flag. */\n enabled: boolean\n /** Rendering mode. */\n mode: 'mica' | 'compat'\n /** Glass blur radius, px (0-40). */\n blur: number\n /** Glass fill frost, 0-100. */\n frost: number\n /** Backdrop brightness, 0-100. */\n brightness: number\n}\n\n/** The whole durable state the plugin persists. */\nexport interface CatppuccinState {\n /** Schema version; anything else is treated as unknown and defaulted. */\n version: typeof STATE_VERSION\n /** Selected flavour (theme id or `off`). */\n flavor: FlavorValue\n /** Glass-layer settings (enable flag + knobs). */\n glass: GlassState\n /** Automatically re-check for updates (boot + periodic, while on). */\n autoCheck: boolean\n /** Release channel the update check chases. */\n updateChannel: UpdateChannel\n /** Per-token `--dsw-*` overrides merged LAST into the active theme. */\n overrides: Record<string, string>\n /** Shiki syntax-highlighting style variant. */\n shikiStyle: ShikiStyle\n}\n\n/** The settings-document section: `CatppuccinState` minus the synthetic\n * `version` field — the official seam resolves defaults, composition and the\n * user layer itself, so no plugin-side version is stored. */\nexport interface CatppuccinSettingsSection {\n /** Selected flavour (theme id or `off`). */\n flavor: FlavorValue\n /** Glass-layer settings (enable flag + knobs). */\n glass: GlassState\n /** Automatically re-check for updates (boot + periodic, while on). */\n autoCheck: boolean\n /** Release channel the update check chases. */\n updateChannel: UpdateChannel\n /** Per-token `--dsw-*` overrides merged LAST into the active theme. */\n overrides: Record<string, string>\n /** Shiki syntax-highlighting style variant. */\n shikiStyle: ShikiStyle\n}\n\n/** Shipped glass defaults — the single source of truth; the client glass layer\n * (`src/client/glass/glass-layer.ts`) derives its knob defaults from here. */\nexport const DEFAULT_GLASS: GlassState = {\n enabled: false,\n mode: 'mica',\n blur: 5,\n frost: 20,\n brightness: 50,\n}\n\n/** Shipped update-check preference: automatic checks on. */\nexport const DEFAULT_AUTO_CHECK = true\n/** Shipped update-check channel: chase the stable `latest` tag. */\nexport const DEFAULT_UPDATE_CHANNEL: UpdateChannel = 'latest'\n/** Shipped syntax-highlighting style. */\nexport const DEFAULT_SHIKI_STYLE: ShikiStyle = 'default'\n\n/** A fully default state: no Catppuccin flavour and no glass. */\nexport function defaultState(): CatppuccinState {\n return {\n version: STATE_VERSION,\n flavor: 'off',\n glass: { ...DEFAULT_GLASS },\n autoCheck: DEFAULT_AUTO_CHECK,\n updateChannel: DEFAULT_UPDATE_CHANNEL,\n overrides: {},\n shikiStyle: DEFAULT_SHIKI_STYLE,\n }\n}\n\n/**\n * Keep only well-formed custom token overrides: string values under a `--`\n * key (the token shape `--dsw-*` names). Everything else is dropped so a\n * hand-edited document can never smuggle junk into the theme registration.\n */\nexport function sanitizeOverrides(input: unknown): Record<string, string> {\n const out: Record<string, string> = {}\n if (typeof input !== 'object' || input === null) return out\n for (const [key, value] of Object.entries(input)) {\n if (typeof value === 'string' && key.startsWith('--')) out[key] = value\n }\n return out\n}\n\n/**\n * Whether a raw overrides map carries entries {@link sanitizeOverrides} would\n * drop — a key that is not a `--` token, or a non-string value.\n *\n * The settings-document schema types `overrides` as a dict of strings only, so\n * a hand-edited document can hold such entries. The client reads them away but\n * never wrote the cleaned map back, so every settings publish re-ran the\n * \"document wins\" adoption for a difference nothing could clear (audit F7).\n * The caller uses this to push the sanitized shape back once, so the document\n * converges instead of drifting forever.\n */\nexport function hasUnpersistableOverrides(raw: unknown): boolean {\n if (typeof raw !== 'object' || raw === null) return false\n return Object.entries(raw).some(([key, value]) => typeof value !== 'string' || !key.startsWith('--'))\n}\n\n/** Clamp a finite number into [min, max]; non-finite values fall back. */\nfunction clampFinite(value: unknown, min: number, max: number, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value)\n ? Math.min(max, Math.max(min, value))\n : fallback\n}\n\n/**\n * Normalize arbitrary input (JSON from disk or the wire) into a valid state:\n * unknown/missing fields fall back to defaults, out-of-range numbers clamp,\n * and unknown flavours/invalid enums fall back too. The Host applies this on\n * both read and write so a corrupt file or a hand-crafted payload can never\n * poison the plugin's settings.\n */\nexport function sanitizeState(input: unknown): CatppuccinState {\n const state = defaultState()\n if (typeof input !== 'object' || input === null) return state\n const raw = input as Record<string, unknown>\n\n const flavor = raw.flavor\n if (typeof flavor === 'string' && (CATPPUCCIN_THEME_IDS as readonly string[]).includes(flavor)) {\n state.flavor = flavor as FlavorValue\n } else if (flavor === 'off') {\n state.flavor = 'off'\n }\n\n const glass = typeof raw.glass === 'object' && raw.glass !== null\n ? raw.glass as Record<string, unknown>\n : {}\n state.glass.enabled = glass.enabled === true\n state.glass.mode = glass.mode === 'compat' ? 'compat' : 'mica'\n state.glass.blur = clampFinite(glass.blur, 0, 40, DEFAULT_GLASS.blur)\n state.glass.frost = clampFinite(glass.frost, 0, 100, DEFAULT_GLASS.frost)\n state.glass.brightness = clampFinite(glass.brightness, 0, 100, DEFAULT_GLASS.brightness)\n\n // Preference fields: absent values keep their shipped defaults, so a v1\n // document (predating them) rolls forward without a migration step.\n state.autoCheck = raw.autoCheck !== false\n state.updateChannel = raw.updateChannel === 'beta' ? 'beta' : 'latest'\n state.overrides = sanitizeOverrides(raw.overrides)\n state.shikiStyle = raw.shikiStyle === 'italic-comments' ? 'italic-comments' : 'default'\n\n return state\n}\n\n/**\n * Version-aware migration of an arbitrary persisted document. Version 1\n * documents roll forward through `sanitizeState` (every field added since\n * v1 has a sanitize-time default, so no structural step exists yet); future\n * versions chain their steps here, oldest first. Documents from a NEWER\n * plugin keep every field `sanitizeState` understands instead of being\n * nuked — a downgrade never destroys user state. The version-upgrade\n * convention lives in `docs/state-migrations.md` (item Y).\n */\nexport function migrate(raw: unknown): CatppuccinState {\n if (typeof raw !== 'object' || raw === null) return defaultState()\n const record = raw as Record<string, unknown>\n const version = typeof record.version === 'number' ? record.version : 1\n // Future schema steps chain here, oldest first:\n // let current: unknown = record\n // if (version < 2) current = migrateV1toV2(current)\n // if (version < 3) current = migrateV2toV3(current)\n // (the state contract of each step is spelled out in docs/state-migrations.md)\n return sanitizeState(record)\n}\n\n/** Whether a normalized state carries nothing beyond the shipped defaults —\n * i.e. the user never actually chose anything worth persisting. Used to tell\n * \"no durable state yet\" apart from \"an explicit default choice\". */\nexport function isDefaultState(state: CatppuccinState): boolean {\n const expected = defaultState()\n return state.flavor === expected.flavor\n && state.glass.enabled === expected.glass.enabled\n && state.glass.mode === expected.glass.mode\n && state.glass.blur === expected.glass.blur\n && state.glass.frost === expected.glass.frost\n && state.glass.brightness === expected.glass.brightness\n && state.autoCheck === expected.autoCheck\n && state.updateChannel === expected.updateChannel\n && Object.keys(state.overrides).length === 0\n && state.shikiStyle === expected.shikiStyle\n}\n\n/** Default settings-document section: no flavour and no glass (mirrors\n * `defaultState()` minus the synthetic `version`). */\nexport function defaultSettingsSection(): CatppuccinSettingsSection {\n return {\n flavor: 'off',\n glass: { ...DEFAULT_GLASS },\n autoCheck: DEFAULT_AUTO_CHECK,\n updateChannel: DEFAULT_UPDATE_CHANNEL,\n overrides: {},\n shikiStyle: DEFAULT_SHIKI_STYLE,\n }\n}\n\n/** Drop the synthetic `version` field: full state → settings-document section. */\nexport function settingsSectionFromState(state: CatppuccinState): CatppuccinSettingsSection {\n return {\n flavor: state.flavor,\n glass: { ...state.glass },\n autoCheck: state.autoCheck,\n updateChannel: state.updateChannel,\n overrides: { ...state.overrides },\n shikiStyle: state.shikiStyle,\n }\n}\n\n/** Lift a settings-document section back into the full state-shaped contract\n * (re-sanitized so a hand-edited document can never poison the plugin). */\nexport function stateFromSettingsSection(section: CatppuccinSettingsSection): CatppuccinState {\n return sanitizeState(section)\n}\n\n/** Whether two settings sections are field-for-field equal (used to skip\n * redundant mirror writes and to recognize the Host echoing our own write). */\nexport function settingsSectionsEqual(a: CatppuccinSettingsSection, b: CatppuccinSettingsSection): boolean {\n return a.flavor === b.flavor\n && a.glass.enabled === b.glass.enabled\n && a.glass.mode === b.glass.mode\n && a.glass.blur === b.glass.blur\n && a.glass.frost === b.glass.frost\n && a.glass.brightness === b.glass.brightness\n && a.autoCheck === b.autoCheck\n && a.updateChannel === b.updateChannel\n && a.shikiStyle === b.shikiStyle\n && Object.keys(a.overrides).every((key) => b.overrides[key] === a.overrides[key])\n && Object.keys(b.overrides).every((key) => a.overrides[key] === b.overrides[key])\n}\n","/**\n * Catppuccin glass layer — one toggleable glassmorphism skin over the whole\n * Web surface, riding on top of the Catppuccin themes. Everything the layer\n * owns is an effect: the CSS hooks ride a `data-dsh-glass` attribute on\n * <html> (the stylesheet only applies under it), the seam stamps ride a\n * MutationObserver, and the page-edge fade bands are DOM elements — so\n * switching the flag off (or unloading the plugin) restores the stock UI\n * exactly: no residue, no reload.\n *\n * The page ground is a SOLID colour: the active theme's own `bg-base`\n * token (Latte / Frappé / Macchiato / Mocha), with the brightness knob\n * mixing white/black straight into it. The earlier animated ambient scene\n * (gradient wash + drifting blobs + hue rotation) was removed in favour of\n * this flat ground.\n *\n * The enable flag and every knob persist in localStorage — the in-browser\n * cache and cross-tab sync bus. The DURABLE copy of the same state lives in\n * the official settings store under the DSH home (namespace `catppuccin` / the\n * profile entry form, see `src/state.ts` — the Host declares it, the Client\n * binds whichever seam the host serves through `src/client/state-sync.ts` and\n * hydrates via `applyRemote` / `getRemoteState`):\n * required because localStorage is per-browser and per-origin, while the DSH\n * home is the machine-wide truth (see the rationale in `src/state.ts`). On\n * profiles without a usable settings transport the layer simply keeps working\n * from localStorage alone. The enable flag and knobs themselves stay\n * client-only visual preferences shared with the plugin alone, needing no host\n * configuration.\n */\nimport type { Context } from '@deepseek-ai/cordis'\n// Type-only: pulls the theme plugin's Context merge (ctx.theme + theme/change).\nimport type {} from '@deepseek-ai/dsh-client-ui-theme/client'\nimport { startGlassSeamStamper } from './glass-seams.ts'\nimport { GLASS_CSS_TEXT } from './glass-css.gen.ts'\nimport { DEFAULT_GLASS, type GlassState } from '../../state.ts'\n\n/** html attribute selecting the glass layer: CSS hooks and page effects. */\nexport const GLASS_ATTRIBUTE = 'data-dsh-glass'\n\n/** html attribute selecting the mica (floating-card) layout rules. */\nexport const GLASS_FLOAT_ATTRIBUTE = 'data-dsh-glass-float'\n\n/** html attribute selecting the compatibility (stock-layout) rules. */\nexport const GLASS_COMPAT_ATTRIBUTE = 'data-dsh-glass-compat'\n\n/** localStorage key carrying the layer enable flag. */\nexport const GLASS_ENABLED_KEY = 'dsh.catppuccin.glass.enabled'\n\n/** Plugin identity stamped onto the lazily-mounted glass <style> tag (the\n * shell's unload cleanup keys off `data-plugin`). */\nconst GLASS_STYLE_PLUGIN = '@nonamelego/dsh-catppuccin'\nconst GLASS_STYLE_TAG_ID = 'glass.module.css'\n\n/** The lazily-mounted glass stylesheet <style> tag (undefined while the\n * layer is off — item II: the glass CSS only enters the document while\n * the glass layer is enabled, instead of being injected at plugin load). */\nlet glassStyleTag: HTMLStyleElement | null = null\n\n/** Default state when nothing is stored yet: off (the stock UI stays stock). */\nexport const DEFAULT_ENABLED = DEFAULT_GLASS.enabled\n\n/** Tunable glass knobs. */\nexport interface GlassSettings {\n /** Rendering mode: mica (frosted floating cards) or the stock layout with a generic glass material. */\n mode: 'mica' | 'compat'\n /** Glass backdrop blur radius, px. */\n blur: number\n /** Glass fill opacity, 0-100 (50 = the shipped look; drives the frost multiplier). */\n frost: number\n /** Backdrop brightness, 0-100 (0 = pure black, 50 = transparent, 100 = pure white; half-range per scheme). */\n brightness: number\n}\n\n/** The full state the settings row mirrors (settings + enable flag + scheme). */\nexport interface GlassRowState extends GlassSettings {\n /** Layer enable flag. */\n enabled: boolean\n /** Resolved palette is dark (the brightness knob darkens). */\n dark: boolean\n}\n\n/**\n * Shipped knob defaults — the knob-only view of `DEFAULT_GLASS` in\n * `src/state.ts` (the single source of truth, inlined into both bundles).\n * The shipped look aligns with the reference project\n * (DSH-Transparent-UI-Plugin / Aqua): mica mode, blur 5px, frost 20\n * (the 0-100 slider maps to a 0-1.4 alpha multiplier via frost/50, so 20\n * reads as a light frost) and neutral backdrop brightness.\n */\nexport const SETTINGS_DEFAULTS: GlassSettings = {\n mode: DEFAULT_GLASS.mode,\n blur: DEFAULT_GLASS.blur,\n frost: DEFAULT_GLASS.frost,\n brightness: DEFAULT_GLASS.brightness,\n}\n\n/** Numeric knob keys and their localStorage names. */\nconst NUMERIC_KEYS = {\n blur: 'dsh.catppuccin.glass.blur',\n frost: 'dsh.catppuccin.glass.frost',\n brightness: 'dsh.catppuccin.glass.brightness',\n} as const\ntype NumericKey = keyof typeof NUMERIC_KEYS\n\n/** The localStorage names of the numeric knobs — the reverse of\n * `NUMERIC_KEYS`. Used by the cross-tab `storage` handler: the event's `key`\n * is a localStorage name (`dsh.catppuccin.glass.blur`), so it must be matched\n * against the VALUES, never with `key in NUMERIC_KEYS` (that tests the object's\n * property names — `blur`/`frost`/`brightness` — and is false for every real\n * storage key, which silently killed cross-tab knob sync; audit F1). */\nconst NUMERIC_STORAGE_KEYS: readonly string[] = Object.values(NUMERIC_KEYS)\n\nconst MODE_KEY = 'dsh.catppuccin.glass.mode'\n\n/** Clamp a numeric knob into its sane range. */\nfunction clampSetting(key: NumericKey, value: number): number {\n const max = key === 'blur' ? 40 : 100\n return Number.isFinite(value) ? Math.min(max, Math.max(0, value)) : SETTINGS_DEFAULTS[key]\n}\n\n/** Read one numeric knob from localStorage (absent/parse failure means the default). */\nfunction readSetting(key: NumericKey): number {\n try {\n const raw = localStorage.getItem(NUMERIC_KEYS[key])\n return raw === null ? SETTINGS_DEFAULTS[key] : clampSetting(key, Number(raw))\n } catch {\n return SETTINGS_DEFAULTS[key]\n }\n}\n\n/** Persist one numeric knob (storage failures keep the in-memory state). */\nfunction writeSetting(key: NumericKey, value: number): void {\n try {\n localStorage.setItem(NUMERIC_KEYS[key], String(value))\n } catch {\n /* in-memory state still applies for this tab */\n }\n}\n\n/** Read the rendering mode ('mica' or 'compat'). */\nfunction readMode(): 'mica' | 'compat' {\n try {\n return localStorage.getItem(MODE_KEY) === 'compat' ? 'compat' : 'mica'\n } catch {\n return 'mica'\n }\n}\n\n/** Persist the rendering mode. */\nfunction writeMode(value: 'mica' | 'compat'): void {\n try {\n localStorage.setItem(MODE_KEY, value)\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/** Read the persisted enable flag (absent storage means the default). */\nfunction readEnabled(): boolean {\n try {\n const raw = localStorage.getItem(GLASS_ENABLED_KEY)\n return raw === null ? DEFAULT_ENABLED : raw === 'true'\n } catch {\n return DEFAULT_ENABLED\n }\n}\n\n/** Persist the enable flag (storage failures keep the in-memory state). */\nfunction writeEnabled(value: boolean): void {\n try {\n localStorage.setItem(GLASS_ENABLED_KEY, String(value))\n } catch {\n /* in-memory state still applies for this tab */\n }\n}\n\n/** Resolved scheme from the theme service (falls back to the body attribute). */\nfunction resolveDark(ctx: Context): boolean {\n try {\n return ctx.theme.getTheme().active.colorScheme === 'dark'\n } catch {\n return document.body.hasAttribute('data-ds-dark-theme')\n }\n}\n\n/**\n * The page-edge fade bands injected while enabled (ported from\n * DSH-Transparent-UI-Plugin): two fixed-position, click-through strips\n * that blur the chat content melting into the viewport edges. Both are\n * removed together on disable. The page ground itself is pure CSS (the\n * body rule), so no backdrop element is needed.\n */\nconst FADE_MARKUP = [\n '<span data-dsh-glass-fade=\"top\" aria-hidden=\"true\"></span>',\n '<span data-dsh-glass-fade=\"bottom\" aria-hidden=\"true\"></span>',\n].join('')\n\n/**\n * Owns the glass layer lifecycle: reads the durable enable flag and knobs,\n * and applies / retracts every layer on change. Cross-tab flips arrive through\n * the storage event; the seam observer and every subscription are released\n * when the plugin fiber is disposed.\n */\nexport class GlassLayer {\n private enabled = false\n private settings: GlassSettings = { ...SETTINGS_DEFAULTS }\n /** Cached snapshot for the settings row (stable reference between changes). */\n private snapshot: GlassRowState\n private readonly listeners = new Set<() => void>()\n private dark = false\n private seamDisposer: (() => void) | undefined\n private readonly ctx: Context\n\n /**\n * @param ctx - owning client context (listeners ride this fiber).\n */\n constructor(ctx: Context) {\n this.ctx = ctx\n this.enabled = readEnabled()\n this.reloadSettings()\n this.dark = resolveDark(ctx)\n this.snapshot = this.buildSnapshot()\n\n ctx.effect(() => {\n const onStorage = (event: StorageEvent): void => {\n if (event.key === null) { this.reloadSettings(); this.enabled = readEnabled(); this.sync() }\n else if (event.key === GLASS_ENABLED_KEY) {\n this.enabled = readEnabled()\n this.sync()\n } else if (event.key === MODE_KEY || NUMERIC_STORAGE_KEYS.includes(event.key)) {\n this.reloadSettings()\n if (this.enabled) this.applySettings()\n this.publish()\n }\n }\n window.addEventListener('storage', onStorage)\n // Follow the Appearance switch: the brightness knob's half-range and\n // the mix direction flip with the resolved scheme. Runs even while\n // disabled so the settings row stays correct.\n const themeListener = ctx.on('theme/change', () => {\n this.dark = resolveDark(ctx)\n if (this.enabled) this.applySettings()\n this.publish()\n })\n return () => {\n window.removeEventListener('storage', onStorage)\n themeListener()\n this.unmount()\n }\n }, 'catppuccin: glass layer lifecycle')\n\n // Apply the restored state: mount the layer when the persisted flag is on\n // (the settings row reflects the same snapshot, so the two stay in sync).\n this.sync()\n }\n\n /** Current state snapshot (stable reference until the next change). */\n getSnapshot(): GlassRowState {\n return this.snapshot\n }\n\n /** Subscribe to snapshot changes. Returns the disposer. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n /** The durable subset of the current layer state (no derived `dark`). */\n getRemoteState(): GlassState {\n return {\n enabled: this.enabled,\n mode: this.settings.mode,\n blur: this.settings.blur,\n frost: this.settings.frost,\n brightness: this.settings.brightness,\n }\n }\n\n /** Overlay durable state hydrated from the Host file: persist it to\n * localStorage (the cache), apply it to the live layer, and republish so\n * the settings row reflects the restored choice. */\n applyRemote(remote: GlassState): void {\n this.enabled = remote.enabled\n this.settings = {\n mode: remote.mode === 'compat' ? 'compat' : 'mica',\n blur: clampSetting('blur', remote.blur),\n frost: clampSetting('frost', remote.frost),\n brightness: clampSetting('brightness', remote.brightness),\n }\n writeEnabled(this.enabled)\n writeMode(this.settings.mode)\n writeSetting('blur', this.settings.blur)\n writeSetting('frost', this.settings.frost)\n writeSetting('brightness', this.settings.brightness)\n this.sync()\n }\n\n /** Flip the layer: persist, then apply or retract every owned effect. */\n setEnabled(value: boolean): void {\n if (value === this.enabled) return\n this.enabled = value\n writeEnabled(value)\n this.sync()\n }\n\n /** Set the rendering mode ('mica' or 'compat'). */\n setMode(value: 'mica' | 'compat'): void {\n if (value === this.settings.mode) return\n this.settings.mode = value\n writeMode(value)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Set the glass blur radius (px). */\n setBlur(value: number): void {\n const next = clampSetting('blur', value)\n if (next === this.settings.blur) return\n this.settings.blur = next\n writeSetting('blur', next)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Set the glass frost amount (0-100). */\n setFrost(value: number): void {\n const next = clampSetting('frost', value)\n if (next === this.settings.frost) return\n this.settings.frost = next\n writeSetting('frost', next)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Set the backdrop brightness (0-100: 0 = pure black, 50 = transparent, 100 = pure white). */\n setBrightness(value: number): void {\n const next = clampSetting('brightness', value)\n if (next === this.settings.brightness) return\n this.settings.brightness = next\n writeSetting('brightness', next)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Restore every knob to the shipped defaults (persisted immediately). */\n resetDefaults(): void {\n this.settings = { ...SETTINGS_DEFAULTS }\n writeMode(this.settings.mode)\n writeSetting('blur', this.settings.blur)\n writeSetting('frost', this.settings.frost)\n writeSetting('brightness', this.settings.brightness)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Re-read every knob from localStorage into memory. */\n private reloadSettings(): void {\n this.settings = {\n mode: readMode(),\n blur: readSetting('blur'),\n frost: readSetting('frost'),\n brightness: readSetting('brightness'),\n }\n }\n\n private buildSnapshot(): GlassRowState {\n return { ...this.settings, enabled: this.enabled, dark: this.dark }\n }\n\n private publish(): void {\n this.snapshot = this.buildSnapshot()\n for (const listener of this.listeners) listener()\n }\n\n private sync(): void {\n if (this.enabled) this.mount()\n else this.unmount()\n this.publish()\n }\n\n /** Write the knob-driven CSS variables and mode attributes onto <html>. */\n private applySettings(): void {\n const style = document.documentElement.style\n style.setProperty('--dsh-glass-blur', `${this.settings.blur}px`)\n // Frost 0-100 → a 0-1.4 alpha multiplier (50 = 1x). Capped so max frost\n // stays translucent frosted glass instead of collapsing to a solid slab.\n style.setProperty('--dsh-glass-frost', String(Math.min(this.settings.frost / 50, 1.4)))\n // Backdrop brightness: dark mode darkens (0 = pure black, 50 = off),\n // light mode brightens (50 = off, 100 = pure white) — the knob's range\n // and the mix direction both follow the resolved scheme. The body\n // background rule mixes these fractions straight into the solid ground.\n const dark = this.dark\n style.setProperty('--dsh-glass-brightness-black', String(dark ? Math.max(0, (50 - this.settings.brightness) / 50) : 0))\n style.setProperty('--dsh-glass-brightness-white', String(dark ? 0 : Math.max(0, (this.settings.brightness - 50) / 50)))\n\n // Rendering mode: the float rules key off data-dsh-glass-float; the\n // compat (generic glass) rules key off data-dsh-glass-compat.\n const compat = this.settings.mode === 'compat'\n document.documentElement.toggleAttribute(GLASS_FLOAT_ATTRIBUTE, !compat)\n document.documentElement.toggleAttribute(GLASS_COMPAT_ATTRIBUTE, compat)\n }\n\n private mount(): void {\n this.ensureStyle()\n document.documentElement.setAttribute(GLASS_ATTRIBUTE, '')\n this.applySettings()\n this.ensureFades()\n if (this.seamDisposer === undefined) this.seamDisposer = startGlassSeamStamper()\n }\n\n private unmount(): void {\n document.documentElement.removeAttribute(GLASS_ATTRIBUTE)\n document.documentElement.removeAttribute(GLASS_FLOAT_ATTRIBUTE)\n document.documentElement.removeAttribute(GLASS_COMPAT_ATTRIBUTE)\n for (const node of document.querySelectorAll('[data-dsh-glass-fade]')) node.remove()\n this.seamDisposer?.()\n this.seamDisposer = undefined\n this.releaseStyle()\n }\n\n /** Mount the glass stylesheet <style> tag (lazy — first enable only;\n * re-append when toggling back on). The CSS text ships in the bundle as\n * `GLASS_CSS_TEXT` (see `glass-css.gen.ts`), so no document work happens\n * while the layer is off and only a detached/re-attached tag marks the\n * on/off boundary after the first mount. */\n private ensureStyle(): void {\n if (glassStyleTag !== null) {\n document.head.append(glassStyleTag)\n return\n }\n const tag = document.createElement('style')\n tag.dataset.plugin = GLASS_STYLE_PLUGIN\n tag.dataset.pluginCss = GLASS_STYLE_TAG_ID\n tag.textContent = GLASS_CSS_TEXT\n document.head.append(tag)\n glassStyleTag = tag\n }\n\n /** Remove the lazily-mounted stylesheet tag (the layer's CSS leaves the\n * document with it; the body attribute removal already made every rule\n * inert). */\n private releaseStyle(): void {\n glassStyleTag?.remove()\n glassStyleTag = null\n }\n\n /** Insert the page-edge fade bands (or reuse the existing ones). */\n private ensureFades(): void {\n if (document.querySelector('[data-dsh-glass-fade]') !== null) return\n const holder = document.createElement('div')\n holder.innerHTML = FADE_MARKUP\n for (const node of Array.from(holder.children)) {\n if (node instanceof HTMLElement) document.body.append(node)\n }\n }\n}\n","/**\n * Catppuccin glass settings row — registered into the General settings\n * section (`settings.general.item`, right under the Catppuccin flavour row).\n * Holds the master on/off switch plus every glass knob: mode (mica /\n * compatibility), blur, frost and backdrop brightness. Every write goes\n * straight through to the glass layer, so the skin moves live.\n */\nimport { useRef, useState, useSyncExternalStore } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { SETTINGS_DEFAULTS, type GlassRowState } from './glass-layer.ts'\nimport type { CatppuccinKey } from '../locales.ts'\nimport css from './GlassRow.module.css'\n\n/** Injected business face: the layer state seat plus every knob write. */\nexport interface GlassRowInjected {\n /** Current layer state snapshot. */\n getState: () => GlassRowState\n /** Subscribe to layer state changes. Returns the disposer. */\n subscribe: (listener: () => void) => () => void\n /** Switch the glass layer on or off. */\n setEnabled: (enabled: boolean) => void\n /** Set the rendering mode ('mica' floating cards or 'compat' stock layout). */\n setMode: (mode: 'mica' | 'compat') => void\n /** Set the glass blur radius, px. */\n setBlur: (value: number) => void\n /** Set the glass frost amount, 0-100. */\n setFrost: (value: number) => void\n /** Set the backdrop brightness, 0-100. */\n setBrightness: (value: number) => void\n /** Restore every knob to the shipped defaults. */\n resetDefaults: () => void\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type GlassRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'> & GlassRowInjected\n\n/** One slider + number box, wired to a single value. */\nfunction Knob(props: {\n label: string\n value: number\n min: number\n max: number\n step: number\n unit: string\n onChange: (value: number) => void\n}): React.JSX.Element {\n const { label, value, min, max, step, unit, onChange } = props\n const clamp = (n: number): number => Math.min(max, Math.max(min, Number.isFinite(n) ? n : min))\n return (\n <label className={css.knob}>\n <span className={css.knobLabel}>{label}</span>\n <input\n type=\"range\"\n className={css.slider}\n min={min}\n max={max}\n step={step}\n value={value}\n // Item Z: the raw number is announced without its unit otherwise. The\n // qualitative tier names stay out of the locale dictionaries on purpose\n // (7 languages × 3 knobs of invented copy buys little over parity).\n aria-valuetext={`${value}${unit}`}\n onChange={(e) => { onChange(clamp(Number(e.target.value))) }}\n />\n <span className={css.numberWrap}>\n <input\n type=\"number\"\n className={css.number}\n min={min}\n max={max}\n step={step}\n value={value}\n onChange={(e) => { onChange(clamp(Number(e.target.value))) }}\n />\n <span className={css.unit}>{unit}</span>\n </span>\n </label>\n )\n}\n\n/** A two-option segmented picker with roving tabindex (item AA): only the\n * selected cell is tabbable, Arrow/Home/End move focus WITHOUT selecting,\n * and Enter/Space (or click) commits — the WAI-ARIA roving-tabindex\n * pattern for segmented controls. */\nfunction Segmented<T extends string>(props: {\n label: string\n value: T\n options: readonly { id: T; label: string }[]\n onSelect: (value: T) => void\n}): React.JSX.Element {\n const { label, value, options, onSelect } = props\n const [focused, setFocused] = useState<T | null>(null)\n const refs = useRef(new Map<T, HTMLButtonElement>())\n\n // The roving tab stop. `value` may match NO option (the preset group gets ''\n // when the knobs are hand-tuned), and `option.id === value` would then leave\n // every cell at tabIndex -1 — the group silently drops out of the tab order\n // and keyboard users cannot reach the presets at all (audit F3). Fall back to\n // the first cell so the group always keeps exactly one tab stop.\n const matchesValue = options.some((option) => option.id === value)\n const anchor = focused ?? (matchesValue ? value : options[0]?.id)\n\n const moveFocus = (direction: 1 | -1 | 'home' | 'end'): void => {\n const current = anchor\n const index = options.findIndex((option) => option.id === current)\n let next: number\n if (direction === 'home') next = 0\n else if (direction === 'end') next = options.length - 1\n else next = Math.min(options.length - 1, Math.max(0, index + direction))\n const target = options[next]\n if (target === undefined) return\n setFocused(target.id)\n refs.current.get(target.id)?.focus()\n }\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>): void => {\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n moveFocus(-1)\n break\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n moveFocus(1)\n break\n case 'Home':\n event.preventDefault()\n moveFocus('home')\n break\n case 'End':\n event.preventDefault()\n moveFocus('end')\n break\n }\n }\n\n return (\n <div className={css.segmented} role=\"group\" aria-label={label}>\n {options.map((option) => (\n <button\n key={option.id}\n ref={(node) => {\n if (node === null) refs.current.delete(option.id)\n else refs.current.set(option.id, node)\n }}\n type=\"button\"\n className={option.id === value ? css.segActive : css.seg}\n aria-pressed={option.id === value}\n tabIndex={option.id === anchor ? 0 : -1}\n onFocus={() => { setFocused(option.id) }}\n onBlur={() => { setFocused((now) => (now === option.id ? null : now)) }}\n onKeyDown={onKeyDown}\n onClick={() => { onSelect(option.id) }}\n >\n {option.label}\n </button>\n ))}\n </div>\n )\n}\n\n/** One-click material presets — blur/frost/brightness triples the row applies\n * through the existing setters (the debounced persist coalesces the burst\n * into one Host write). Brightness stays neutral (50) so every preset works\n * in both schemes; the sliders remain for fine tuning. */\nconst GLASS_PRESETS: readonly { id: string; key: CatppuccinKey; blur: number; frost: number; brightness: number }[] = [\n { id: 'clear', key: 'glass.presetClear', blur: 0, frost: 8, brightness: 50 },\n { id: 'standard', key: 'glass.presetStandard', blur: SETTINGS_DEFAULTS.blur, frost: SETTINGS_DEFAULTS.frost, brightness: SETTINGS_DEFAULTS.brightness },\n { id: 'frosted', key: 'glass.presetFrosted', blur: 12, frost: 45, brightness: 50 },\n]\n\n/**\n * Render the glass row: title, the master switch, and — while enabled — the\n * mode picker and every knob.\n * @param props - composed slot props.\n * @returns the General section row.\n */\nexport function GlassRow({ t, getState, subscribe, setEnabled, setMode, setBlur, setFrost, setBrightness, resetDefaults }: GlassRowProps): React.JSX.Element {\n const state = useSyncExternalStore(subscribe, getState)\n const { enabled, mode, blur, frost, brightness, dark } = state\n\n // The brightness knob only ever offers the half that makes sense for the\n // resolved scheme: dark mode darkens (0-50), light mode brightens (50-100).\n const bgMin = dark ? 0 : 50\n const bgMax = dark ? 50 : 100\n const bgDisplay = Math.min(bgMax, Math.max(bgMin, brightness))\n\n // The preset whose knobs exactly match the live state (none = custom).\n const activePreset = GLASS_PRESETS.find(\n (p) => p.blur === blur && p.frost === frost && p.brightness === brightness,\n )?.id ?? ''\n\n return (\n <div className={css.group}>\n <div className={css.title}>\n {t('glass.title')}\n <span\n role=\"img\"\n aria-label={t('glass.helpLabel')}\n title={t('glass.help')}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n cursor: 'help',\n userSelect: 'none',\n marginLeft: 6,\n }}\n >\n ?\n </span>\n </div>\n <div className={css.description}>{t('glass.description')}</div>\n <div className={css.controls}>\n <div className={css.row}>\n <span className={css.rowLabel}>{t('glass.enable')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t('glass.enable')}\n className={enabled ? css.toggleOn : css.toggle}\n onClick={() => { setEnabled(!enabled) }}\n >\n <span className={css.check} aria-hidden=\"true\">{enabled ? '✓' : ''}</span>\n </button>\n </div>\n {enabled && (\n <>\n <div className={css.row}>\n <span className={css.rowLabel}>{t('glass.mode')}</span>\n <Segmented\n label={t('glass.mode')}\n value={mode}\n options={[\n { id: 'mica', label: t('glass.modeMica') },\n { id: 'compat', label: t('glass.modeCompat') },\n ]}\n onSelect={setMode}\n />\n </div>\n <div className={css.rowHint}>{t('glass.modeHint')}</div>\n <div className={css.row}>\n <span className={css.rowLabel}>{t('glass.presets')}</span>\n <Segmented\n label={t('glass.presets')}\n value={activePreset}\n options={GLASS_PRESETS.map((p) => ({ id: p.id, label: t(p.key) }))}\n onSelect={(id) => {\n const preset = GLASS_PRESETS.find((p) => p.id === id)\n if (preset === undefined) return\n setBlur(preset.blur)\n setFrost(preset.frost)\n setBrightness(preset.brightness)\n }}\n />\n </div>\n <Knob label={t('glass.blur')} value={blur} min={0} max={40} step={0.5} unit=\"px\" onChange={setBlur} />\n <Knob label={t('glass.frost')} value={frost} min={0} max={100} step={1} unit=\"%\" onChange={setFrost} />\n <Knob label={t('glass.brightness')} value={bgDisplay} min={bgMin} max={bgMax} step={1} unit=\"%\" onChange={setBrightness} />\n <div className={css.knobHint}>\n {t(dark ? 'glass.brightnessHintDark' : 'glass.brightnessHintLight')}\n </div>\n <div className={css.row}>\n <button type=\"button\" className={css.resetButton} onClick={() => { resetDefaults() }}>\n {t('glass.reset')}\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n )\n}\n","/**\n * \"Feedback & support\" settings row — the section's closing row: a link to\n * the GitHub issue tracker and a link to the repository (the polite star\n * ask). Added 2026-10-11: the plugin previously had NO in-app path to either\n * — a user who hit a problem had to already know the repo exists.\n *\n * No injected face on purpose: the row is pure copy plus two static URLs, so\n * it registers without an `inject` factory (the locale seat is all it needs)\n * and renders identically in both homes — the General settings section and\n * the plugin's own detail page in the Plugin manager (`detail-card.tsx`).\n *\n * Both links open in a new tab/window (`target=\"_blank\"`): without it the\n * click would navigate the DSH UI itself away from the app.\n */\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\n\n/**\n * GitHub repository — where a star lands. Keep the `-theme` name: it is the\n * current repo name (the pre-rename URL only redirects), and only COMPLETE\n * GitHub URLs use it (AGENTS.md「项目身份速览:三套名字」).\n */\nexport const REPO_URL = 'https://github.com/NoNameLeGo/dsh-catppuccin-theme'\n\n/** GitHub issue tracker — where feedback lands. */\nexport const ISSUES_URL = `${REPO_URL}/issues`\n\n/** Full component props: runtime share + locale seat. No injected face. */\nexport type LinksRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'>\n\n/** The row's links: token-coloured, underlined, quiet. */\nconst linkStyle: React.CSSProperties = {\n color: 'var(--dsw-alias-state-business-primary)',\n fontSize: 12,\n lineHeight: '18px',\n textDecoration: 'underline',\n textUnderlineOffset: 3,\n}\n\n/**\n * Render the feedback row: a title and the two links.\n * @param props - composed slot props.\n * @returns the row element tree.\n */\nexport function LinksRow({ t }: LinksRowProps): React.JSX.Element {\n return (\n <div style={{ borderBottom: '1px solid var(--dsw-alias-border-l2)', display: 'flex', flexDirection: 'column', gap: '10px', padding: '16px 0' }}>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 14, lineHeight: '22px' }}>\n {t('links.title')}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}>\n <a href={ISSUES_URL} target=\"_blank\" rel=\"noreferrer noopener\" style={linkStyle}>\n {t('links.issue')}\n </a>\n <a href={REPO_URL} target=\"_blank\" rel=\"noreferrer noopener\" style={linkStyle}>\n {t('links.star')}\n </a>\n </div>\n </div>\n )\n}\n","/**\n * Update-check settings row — one General-section preference row that asks\n * the Host's `/catppuccin/check-update` route for the latest published npm\n * version and reports whether this install is current. Detection is Host-side\n * (Node fetch, no CORS, profile probe included); the row renders the verdict\n * and, when an update is available, offers the copyable CLI upgrade command\n * whose profile name the Host already probed. Upgrading itself stays a\n * terminal action (`dsh plugin … add @latest`) — the row never touches the\n * profile workspace.\n *\n * Beyond the check button the row carries:\n * - the auto-check switch (item H) and the release-channel segmented pick\n * (item I), both persisted through the durable state;\n * - an automatic retry 30s after a failed check (item V) with a countdown;\n * - a conflict banner (item C/X) when a durable write from another window\n * superseded a local change (\"另一窗口已更新,本地改动未保存\");\n * - the latest auto-check verdict (item H) surfaced on mount;\n * - a \"?\" help affordance (item J, native `title` tooltip).\n */\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { UpdateCheckPayload, UpdateErrorCode, UpdateChannel } from '../update-check.ts'\nimport type { CatppuccinKey } from './locales.ts'\n\n/** Auto-retry scheduled after a failed check (item V): one retry after 30s,\n * then it stops — the discipline lives here in the row, never in a hanging\n * route request. */\nexport const UPDATE_RETRY_AFTER_MS = 30_000\n\n/** Injected business face of the row (assembled in apply). */\nexport interface UpdateRowInjected {\n /** Ask the Host for the update verdict (same-origin fetch of the route).\n * The channel preference rides the query string (item I). */\n check: (channel: UpdateChannel) => Promise<UpdateCheckPayload>\n /** Whether automatic checks are on (item H). */\n autoCheck: () => boolean\n /** Set the auto-check preference (persists durably + re-arms timers). */\n setAutoCheck: (value: boolean) => void\n /** The persisted release channel (item I). */\n channel: () => UpdateChannel\n /** Set the release channel (persists durably). */\n setChannel: (channel: UpdateChannel) => void\n /** Subscribe to preference changes (auto-check / channel). */\n subscribePrefs: (listener: () => void) => () => void\n /** The latest auto-check verdict, or null before the first one (item H). */\n lastAutoResult: () => UpdateCheckPayload | null\n /** Subscribe to durable-write conflict notices (item C/X). */\n subscribeConflict: (listener: () => void) => () => void\n /** Number of conflicts this session has seen (item C/X). */\n conflictCount: () => number\n /** The active DSH locale id — for locale-aware formatting (timestamps).\n * `toLocaleString()` with no argument uses the BROWSER locale, which drifts\n * from the interface language as soon as the user picks one in Settings. */\n activeLocale: () => string\n /** Subscribe to locale switches, so a language change re-formats the row. */\n subscribeLocale: (listener: () => void) => () => void\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type UpdateRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'> & UpdateRowInjected\n\n/** One phase of the row's interaction. */\ntype Phase = 'idle' | 'checking' | 'done'\n\n/** Copy the upgrade command; falls back to no-op when the clipboard is unavailable. */\nasync function copyCommand(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n return false\n }\n}\n\n/** Map a stable error code to its locale key (unknown codes fall back to the generic message). */\nfunction errorKey(code: UpdateErrorCode | undefined): CatppuccinKey {\n switch (code) {\n case 'registry-unreachable': return 'update.err.registry'\n case 'registry-http': return 'update.err.http'\n case 'no-dist-tags': return 'update.err.noTags'\n case 'invalid-response': return 'update.err.invalid'\n case 'network.local': return 'update.err.networkLocal'\n case 'network.upstream': return 'update.err.networkUpstream'\n default: return 'update.failed'\n }\n}\n\nconst switchBase: React.CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n flex: 'none',\n width: 44,\n height: 24,\n padding: 0,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n background: 'var(--dsw-alias-bg-layer-2)',\n cursor: 'pointer',\n}\n\nconst knobStyle: React.CSSProperties = {\n position: 'absolute',\n top: 3,\n left: 3,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n background: 'var(--dsw-alias-label-tertiary)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 10,\n lineHeight: 1,\n transition: 'transform 0.18s cubic-bezier(0.4, 0, 0.2, 1)',\n}\n\nconst buttonStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 12px',\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l1)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary)',\n cursor: 'pointer',\n font: 'inherit',\n}\n\n/**\n * Render the update-check row: title, description, auto-check switch,\n * channel pick, a check button, and the verdict once checked.\n * @param props - composed slot props.\n * @returns the row element tree.\n */\nexport function UpdateRow({\n t,\n check,\n autoCheck,\n setAutoCheck,\n channel,\n setChannel,\n subscribePrefs,\n lastAutoResult,\n subscribeConflict,\n conflictCount,\n activeLocale,\n subscribeLocale,\n}: UpdateRowProps): React.JSX.Element {\n const [phase, setPhase] = useState<Phase>('idle')\n const [payload, setPayload] = useState<UpdateCheckPayload | null>(null)\n const [copied, setCopied] = useState(false)\n const autoCheckOn = useSyncExternalStore(subscribePrefs, autoCheck)\n const channelValue = useSyncExternalStore(subscribePrefs, channel)\n const conflicts = useSyncExternalStore(subscribeConflict, conflictCount)\n // The timestamp follows the DSH locale, not the browser: the two only agree\n // until the user picks a language in Settings (2026-09-21 audit).\n const locale = useSyncExternalStore(subscribeLocale, activeLocale)\n const [dismissedConflicts, setDismissedConflicts] = useState(0)\n // Item V: ONE automatic retry after a failure, 30s later (\"仍失败则停\").\n const [retryRemaining, setRetryRemaining] = useState<number | null>(null)\n const retryTimer = useRef<number | undefined>(undefined)\n const tickerTimer = useRef<number | undefined>(undefined)\n // Auto-retries already spent since the last user-initiated check. The retry\n // itself calls `runCheck` (not `runManualCheck`), so a retry that fails\n // again hits this guard and stops instead of re-scheduling forever.\n const retriesUsed = useRef(0)\n const mounted = useRef(true)\n\n /** Drop a pending auto-retry (its timeout and its countdown ticker). */\n const cancelRetry = (): void => {\n if (retryTimer.current !== undefined) {\n window.clearTimeout(retryTimer.current)\n retryTimer.current = undefined\n }\n if (tickerTimer.current !== undefined) {\n window.clearInterval(tickerTimer.current)\n tickerTimer.current = undefined\n }\n setRetryRemaining(null)\n }\n\n // The channel is resolved at CALL time (audit F6): the default used to be the\n // render-closure's `channelValue`, so the 30 s auto-retry — and any check\n // fired from a stale render — queried the channel that was current when the\n // handler was created, not the one the user has since picked.\n const runCheck = async (withChannel?: UpdateChannel): Promise<void> => {\n cancelRetry()\n setPhase('checking')\n setCopied(false)\n let next: UpdateCheckPayload\n try {\n next = await check(withChannel ?? channel())\n } catch {\n next = { ok: false, code: 'network.local', error: 'network.local' }\n }\n setPayload(next)\n setPhase('done')\n if (!next.ok && retriesUsed.current === 0) {\n retriesUsed.current = 1\n const target = Date.now() + UPDATE_RETRY_AFTER_MS\n setRetryRemaining(UPDATE_RETRY_AFTER_MS / 1000)\n const ticker = window.setInterval(() => {\n const remaining = Math.max(0, Math.ceil((target - Date.now()) / 1000))\n setRetryRemaining(remaining)\n if (remaining <= 0) {\n window.clearInterval(ticker)\n tickerTimer.current = undefined\n }\n }, 1000)\n tickerTimer.current = ticker\n retryTimer.current = window.setTimeout(() => {\n if (mounted.current) void runCheck()\n else cancelRetry()\n }, UPDATE_RETRY_AFTER_MS)\n }\n }\n\n /** A user-initiated check: re-arms the one auto-retry budget (item V). */\n const runManualCheck = (): void => {\n retriesUsed.current = 0\n void runCheck()\n }\n\n useEffect(() => {\n mounted.current = true\n return () => {\n mounted.current = false\n if (retryTimer.current !== undefined) window.clearTimeout(retryTimer.current)\n if (tickerTimer.current !== undefined) window.clearInterval(tickerTimer.current)\n }\n }, [])\n\n const autoResult = lastAutoResult()\n const localInstall = payload?.ok === true && payload.installSource !== undefined\n && payload.installSource !== 'registry'\n // DSH Desktop adapts the copy: its target profile comes from the Desktop\n // service and the hint/restart text says so, while standard dsh web keeps\n // the terminal copy.\n const isDesktop = payload?.ok === true && payload.env === 'desktop'\n // The official Electron shell has no CLI path a user can reach (its Plugins\n // page is the only way: delete → re-add the package name), so it gets the\n // bare `pkg@tag` spec plus the page instructions instead of a shell command.\n const officialDesktop = payload?.ok === true && payload.shell === 'official-desktop'\n const upgradeValue = payload?.ok === true\n ? (officialDesktop ? payload.updateSpec : payload.updateCommand)\n : undefined\n const showConflict = conflicts > dismissedConflicts\n\n return (\n <div style={{ borderBottom: '1px solid var(--dsw-alias-border-l2)', display: 'flex', flexDirection: 'column', gap: '10px', padding: '16px 0' }}>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 14, lineHeight: '22px', display: 'flex', alignItems: 'center' }}>\n {t('update.title')}\n <span\n role=\"img\"\n aria-label={t('update.helpLabel')}\n title={t('update.help')}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n cursor: 'help',\n userSelect: 'none',\n marginLeft: 6,\n flex: 'none',\n }}\n >\n ?\n </span>\n </div>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.description')}\n </div>\n\n {/* Conflict banner (item C/X): another window's durable write won. */}\n {showConflict && (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center', padding: '6px 10px', borderRadius: 8, border: '1px solid var(--dsw-alias-border-l2)', background: 'var(--dsw-alias-state-business-tertiary)' }}>\n <span style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.conflict')}\n </span>\n <button\n type=\"button\"\n aria-label={t('update.conflictDismiss')}\n onClick={() => { setDismissedConflicts(conflicts) }}\n style={{ ...buttonStyle, padding: '2px 8px', fontSize: 12 }}\n >\n ✕\n </button>\n </div>\n )}\n\n {/* Auto-check + channel preferences (items H/I). */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px', alignItems: 'center' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.autoCheck')}\n </span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={autoCheckOn}\n aria-label={t('update.autoCheck')}\n onClick={() => { setAutoCheck(!autoCheckOn) }}\n style={{ ...switchBase, background: autoCheckOn ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-bg-layer-2)' }}\n >\n <span aria-hidden=\"true\" style={{ ...knobStyle, transform: autoCheckOn ? 'translateX(22px)' : undefined, background: autoCheckOn ? 'var(--dsw-alias-bg-layer-1)' : 'var(--dsw-alias-label-tertiary)' }}>\n {autoCheckOn ? '✓' : ''}\n </span>\n </button>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.channel')}\n </span>\n <div style={{ display: 'inline-flex', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, overflow: 'hidden' }} role=\"group\" aria-label={t('update.channel')}>\n {(['latest', 'beta'] as const).map((option, index) => (\n <button\n key={option}\n type=\"button\"\n aria-pressed={channelValue === option}\n onClick={() => { setChannel(option) }}\n style={{\n height: 26,\n padding: '0 12px',\n border: 'none',\n borderLeft: index > 0 ? '1px solid var(--dsw-alias-border-l2)' : undefined,\n background: channelValue === option ? 'var(--dsw-alias-state-business-tertiary)' : 'transparent',\n color: channelValue === option ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-label-secondary)',\n fontSize: 12,\n lineHeight: '18px',\n cursor: 'pointer',\n }}\n >\n {t(option === 'latest' ? 'update.channelLatest' : 'update.channelBeta')}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n {/* Auto-check verdict surfaced at mount (item H). */}\n {autoResult?.ok === true && autoResult.outdated === true && autoResult.latest !== undefined && (\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.autoAvailable')} <strong>{autoResult.latest}</strong>\n </div>\n )}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <button type=\"button\" disabled={phase === 'checking'} onClick={runManualCheck} style={{ ...buttonStyle, cursor: phase === 'checking' ? 'default' : 'pointer', opacity: phase === 'checking' ? 0.6 : 1 }}>\n {phase === 'checking' ? t('update.checking') : t('update.check')}\n </button>\n {payload?.ok === true && payload.current !== undefined && (\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.current')} {payload.current}\n </span>\n )}\n {payload?.ok === true && payload.checkedAt !== undefined && (\n <span style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 11, lineHeight: '18px' }}>\n {t('update.checkedAt')} {new Date(payload.checkedAt).toLocaleString(locale)}\n </span>\n )}\n </div>\n\n {phase === 'done' && payload !== null && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n {payload.ok === true ? (\n payload.outdated === true && payload.latest !== undefined ? (\n <>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.available')} <strong>{payload.latest}</strong>\n </div>\n {upgradeValue !== undefined && (\n <>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {officialDesktop\n ? t('update.commandHintOfficialDesktop')\n : isDesktop\n ? t('update.commandHintDesktop').replace('{profile}', payload.profile ?? '')\n : payload.profileDetected === true && payload.profile !== undefined\n ? t('update.commandHintDetected').replace('{profile}', payload.profile)\n : t('update.commandHint')}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <code style={{\n flex: '1 1 260px',\n padding: '6px 10px',\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l1)',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 12,\n lineHeight: '18px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n }}>\n {upgradeValue}\n </code>\n <button\n type=\"button\"\n onClick={() => { void copyCommand(upgradeValue).then(setCopied) }}\n style={{ ...buttonStyle, cursor: 'pointer' }}\n >\n {copied ? t('update.copied') : t(officialDesktop ? 'update.copySpec' : 'update.copy')}\n </button>\n </div>\n {localInstall && (\n <div style={{ color: 'var(--dsw-alias-label-warning, var(--dsw-alias-label-tertiary))', fontSize: 12, lineHeight: '18px' }}>\n {t('update.localInstall')}\n </div>\n )}\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t(isDesktop ? 'update.restartHintDesktop' : 'update.restartHint')}\n </div>\n </>\n )}\n </>\n ) : (\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.upToDate')}\n </div>\n )\n ) : (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <span style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t(errorKey(payload.code))}\n </span>\n {retryRemaining !== null && retryRemaining > 0 && (\n <span style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.retryHint').replace('{s}', String(retryRemaining))}\n </span>\n )}\n <button type=\"button\" onClick={runManualCheck} style={{ ...buttonStyle, cursor: 'pointer' }}>\n {t('update.retry')}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}","/**\n * Plugins-page card — the settings section in the middle of this plugin's own\n * detail page in the Plugin manager (the block ABOVE \"包含的组件\").\n *\n * Why this file exists (evidence, 2026-10-03, official shell 0.2.0-rc.2): the\n * bundle detail page renders\n * `renderSlot('plugins.bundle.config', { view: 'page' }, { entryKey: pkg.name })`\n * (`dsh-client-ui-plugin-manager`), and that `[data-plugin-config]` section\n * exists ONLY when a plugin registers into it. The page's config ledger reads\n * `ctx.slots.entries('plugins.bundle.config')`, so an unregistered slot leaves\n * the page with no settings area at all — which is what this plugin showed\n * before this card. Two upstream references do the same thing:\n * - official `ui-settings-agent-loop` / `ui-settings-shell` register\n * `plugins.item` (the official-plugin card) with `id` / `order` / `label`;\n * - community `dsh-context` (0.60.0) registers THIS slot with\n * `key = its package name` — the shape the screenshot showed.\n * Both wrap the registration in `configForms.whileServed([ns], …)`, which is\n * also why this card appears/disappears with the namespace instead of leaving\n * an empty section behind.\n *\n * `autoGenerate` is NOT the switch here: it is only reported to clients (the\n * host's `describe()` does not filter on it and the page's `formFor()` only\n * looks the namespace up), and registering the slot above is what makes the\n * section render. The Host half keeps `configure({ auto: false })` because\n * this plugin genuinely ships its own UI.\n *\n * Not a second implementation: the card renders the SAME four rows the\n * General section shows and is handed the same injected faces, so both homes\n * read and write the one durable section (`CATPPUCCIN_ENTRY_ID`). The only\n * cost of the second home is that the rows exist twice in the DOM when\n * both are open — each instance subscribes for itself, so no state is shared\n * behind the framework's back (the feedback row has no state at all).\n */\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CatppuccinRow, type CatppuccinRowInjected } from './CatppuccinRow.tsx'\nimport { GlassRow, type GlassRowInjected } from './glass/glass-row.tsx'\nimport { LinksRow } from './LinksRow.tsx'\nimport { UpdateRow, type UpdateRowInjected } from './UpdateRow.tsx'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n /**\n * One settings page on a BUNDLE's detail page in the Plugin manager,\n * keyed by the bundle's PACKAGE NAME (`{ entryKey: pkg.name }`) — for this\n * plugin `@nonamelego/dsh-catppuccin`, NOT the profile entry id the\n * namespace is keyed by (`CATPPUCCIN_ENTRY_ID`). The section renders only\n * while an entry is registered; `slots.inject` waits for this declaration,\n * so a host without the Plugin manager simply never fires.\n *\n * Declared here because this repo's devDependency (`dsh-client-ui-settings`\n * at the 0.1.7 line) predates the Plugin manager while the RUNNING host\n * (0.2.0-rc.2) has it. A future devDependency bump that carries this member\n * merges with this one and must then be reconciled (identical duplicates\n * merge silently; a different shape is a compile error — that error is the\n * signal to delete this declaration).\n */\n 'plugins.bundle.config': {\n kind: 'keyed'\n scope: 'root'\n }\n }\n}\n\n/** Injected business face of the card: the three rows' own faces, unchanged. */\nexport interface CatppuccinDetailCardInjected {\n /** Catppuccin flavour row (registered themes + pick). */\n flavor: CatppuccinRowInjected\n /** Glass-layer row (enable flag + knobs). */\n glass: GlassRowInjected\n /** Update-check row (version, channel, check button). */\n update: UpdateRowInjected\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type CatppuccinDetailCardProps =\n PropsRuntime<'plugins.bundle.config'> & PropsLocale<'catppuccin'> & CatppuccinDetailCardInjected\n\n/**\n * Render the four preference rows on the plugin's own detail page.\n *\n * The rows carry their own title, help affordance and spacing (a bottom\n * border each), so the card is a plain column — the page owns the section\n * chrome (`[data-plugin-config]`).\n * @param props - the injected faces plus the framework seats.\n * @returns the stacked rows.\n */\nexport function CatppuccinDetailCard(props: CatppuccinDetailCardProps): React.JSX.Element {\n return (\n <div data-catppuccin-detail-card style={{ display: 'flex', flexDirection: 'column' }}>\n <CatppuccinRow {...props.flavor} t={props.t} />\n <GlassRow {...props.glass} t={props.t} />\n <UpdateRow {...props.update} t={props.t} />\n <LinksRow t={props.t} />\n </div>\n )\n}\n","/**\n * Catppuccin settings-row copy. The zh dictionary is the key-set source of\n * truth; every other dictionary mirrors it (guarded by tests/locales.spec.ts\n * asserting key-set equality against `zh`).\n */\n\n/** Simplified Chinese dictionary. */\nexport const zh = {\n 'row.title': 'Catppuccin 主题',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha 四款配色,一键切换。',\n 'row.off': '跟随系统',\n 'row.helpLabel': '关于 Catppuccin 主题',\n 'row.help': 'Catppuccin 社区出品的四款配色:Latte(浅色)、Frappé / Macchiato / Mocha(深色)。选择后立即生效并持久保存。',\n 'row.shikiStyle': '代码高亮风格',\n 'row.shikiDefault': '默认',\n 'row.shikiItalicComments': '柔和注释',\n 'row.overrides': '自定义覆盖',\n 'row.overridesHint': '按「--dsw-* 变量: 值」覆盖单个配色 token,例如 --dsw-static-blue-500: #89b4fa。键名与值都在失焦时生效,清空值即删除。',\n 'row.overridesEmpty': '暂无覆盖。点击「+ 添加」新增一条 token 覆盖。',\n 'row.overridesAdd': '添加',\n 'row.overridesRemove': '删除此覆盖',\n 'row.overridesKey': 'token 名称',\n 'row.overridesValue': 'token 值',\n 'flavor.latte.subtitle': '浅色',\n 'flavor.frappe.subtitle': '深色',\n 'flavor.macchiato.subtitle': '深色',\n 'flavor.mocha.subtitle': '深色',\n 'glass.title': '玻璃质感',\n 'glass.description': '顶栏、侧边栏、输入框、统计行、轨迹视图的磨砂玻璃效果,一键开关。',\n 'glass.helpLabel': '关于玻璃质感',\n 'glass.help': '在 Catppuccin 主题之上叠加磨砂玻璃皮肤:悬浮卡片(云母效果)或保持原版排版的兼容模式。模糊度、磨砂度、背景亮度均可调,并支持清透 / 标准 / 磨砂三档预设。云母效果会在顶栏、输入框等大面积区域做背景模糊,流式输出时较吃 GPU——在意性能请用兼容模式,或选「清透」预设。',\n 'glass.enable': '总开关',\n 'glass.mode': '模式',\n 'glass.modeMica': '云母效果',\n 'glass.modeCompat': '兼容模式',\n 'glass.modeHint': '云母效果把界面改成悬浮磨砂卡片;兼容模式保持原版排版,只换玻璃材质(不模糊大面积区域,性能更稳妥)',\n 'glass.presets': '预设',\n 'glass.presetClear': '清透',\n 'glass.presetStandard': '标准',\n 'glass.presetFrosted': '磨砂',\n 'glass.blur': '玻璃模糊度',\n 'glass.frost': '磨砂度',\n 'glass.brightness': '背景亮度',\n 'glass.brightnessHintDark': '深色模式:0 压暗至纯黑,50 原样',\n 'glass.brightnessHintLight': '浅色模式:50 原样,100 提亮至纯白',\n 'glass.reset': '还原默认值',\n 'update.title': '检查 Catppuccin 插件更新',\n 'update.description': '检测本插件(dsh-catppuccin)在 npm 上的最新版本,判断当前安装是否需要升级。',\n 'update.helpLabel': '关于更新检查',\n 'update.help': '向 npm registry 查询本插件的最新版本。开启「自动检查」后会在启动时与每 6 小时自动检查;渠道选 beta 可追踪预发布版本。',\n 'update.autoCheck': '自动检查更新',\n 'update.channel': '渠道',\n 'update.channelLatest': '稳定版',\n 'update.channelBeta': 'Beta 版',\n 'update.check': '检查更新',\n 'update.checking': '检查中…',\n 'update.current': '当前版本',\n 'update.upToDate': '已是最新版本 🎉',\n 'update.available': '发现新版本:',\n 'update.autoAvailable': '自动检查发现新版本:',\n 'update.commandHint': '在终端运行以下命令升级(把 web 换成你的 profile 名):',\n 'update.commandHintDetected': '已自动探测到 profile「{profile}」,在终端运行以下命令升级:',\n 'update.commandHintDesktop': '已检测到你在使用 DSH Desktop,目标 profile「{profile}」,请在 DSH 终端中运行以下命令升级:',\n 'update.commandHintOfficialDesktop': '已检测到官方桌面版(DeepSeek Harness 客户端):它没有命令行升级入口——请在**插件界面**里先删除本插件,再把下面的包名粘进「添加插件」重新安装。',\n 'update.restartHint': '升级完成后重启 dsh web 生效。',\n 'update.restartHintDesktop': '升级完成后重启 DSH Desktop 生效。',\n 'update.copy': '复制命令',\n 'update.copySpec': '复制包名',\n 'update.copied': '已复制 ✓',\n 'update.failed': '检查失败,请稍后重试。',\n 'update.retry': '重试',\n 'update.retryHint': '{s} 秒后自动重试…',\n 'update.checkedAt': '检查时间',\n 'update.localInstall': '检测到本地链接/源码安装,npm 升级命令可能不适用——请用 git pull 或重新构建。',\n 'update.conflict': '另一窗口已更新,本地改动未保存。',\n 'update.conflictDismiss': '关闭提示',\n 'update.err.registry': '无法连接 npm registry,请检查网络后重试。',\n 'update.err.http': 'npm registry 返回异常状态码,请稍后重试。',\n 'update.err.noTags': 'npm registry 未返回可用的版本标签。',\n 'update.err.invalid': 'npm registry 返回了无法解析的数据。',\n 'update.err.networkLocal': '无法连接插件宿主——请检查你的网络后刷新页面重试。',\n 'update.err.networkUpstream': 'npm registry 暂时不可用(请求超时),请稍后重试。',\n 'links.title': '反馈与支持',\n 'links.issue': '对 Catppuccin 外观插件有问题或建议?欢迎在 GitHub 提 Issue',\n 'links.star': '喜欢这个 Catppuccin 外观插件?点一个 Star ⭐',\n} as const\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin theme',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, one click away.',\n 'row.off': 'Follow system',\n 'row.helpLabel': 'About the Catppuccin theme',\n 'row.help': 'Four palettes from the Catppuccin community: Latte (light), Frappé / Macchiato / Mocha (dark). Applies instantly and persists.',\n 'row.shikiStyle': 'Code highlight style',\n 'row.shikiDefault': 'Default',\n 'row.shikiItalicComments': 'Soft comments',\n 'row.overrides': 'Custom overrides',\n 'row.overridesHint': 'Override individual colour tokens as \"--dsw-* variable: value\", e.g. --dsw-static-blue-500: #89b4fa. Both fields apply on blur; an empty value deletes the entry.',\n 'row.overridesEmpty': 'No overrides yet. Click \"+ Add\" to create one.',\n 'row.overridesAdd': 'Add',\n 'row.overridesRemove': 'Remove this override',\n 'row.overridesKey': 'Token name',\n 'row.overridesValue': 'Token value',\n 'flavor.latte.subtitle': 'Light',\n 'flavor.frappe.subtitle': 'Dark',\n 'flavor.macchiato.subtitle': 'Dark',\n 'flavor.mocha.subtitle': 'Dark',\n 'glass.title': 'Glassmorphism',\n 'glass.description': 'Frosted glass for the top bar, sidebar, composer, stats line and trajectory view — one click on/off.',\n 'glass.helpLabel': 'About glassmorphism',\n 'glass.help': 'A frosted-glass skin layered over the Catppuccin theme: floating cards (Mica) or the stock layout with a glass material (Compatibility). Blur, frost and backdrop brightness are tunable, with Clear / Standard / Frosted presets. Mica blurs large areas (top bar, composer), so it costs GPU while output streams — pick Compatibility or the Clear preset if that matters.',\n 'glass.enable': 'Master switch',\n 'glass.mode': 'Mode',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Compatibility',\n 'glass.modeHint': 'Mica restyles the UI into floating frosted cards; Compatibility keeps the stock layout and only swaps the material to glass (no large-area blur — the lighter option)',\n 'glass.presets': 'Presets',\n 'glass.presetClear': 'Clear',\n 'glass.presetStandard': 'Standard',\n 'glass.presetFrosted': 'Frosted',\n 'glass.blur': 'Glass blur',\n 'glass.frost': 'Frost',\n 'glass.brightness': 'Backdrop brightness',\n 'glass.brightnessHintDark': 'Dark mode: 0 fades to pure black, 50 unchanged',\n 'glass.brightnessHintLight': 'Light mode: 50 unchanged, 100 brightens to pure white',\n 'glass.reset': 'Reset to defaults',\n 'update.title': 'Check for Catppuccin plugin updates',\n 'update.description': 'Checks npm for the latest dsh-catppuccin release and whether this install is current.',\n 'update.helpLabel': 'About update checks',\n 'update.help': 'Queries the npm registry for the latest release of this plugin. With auto-check on, a check runs at startup and every 6 hours; the Beta channel also chases prereleases.',\n 'update.autoCheck': 'Auto-check for updates',\n 'update.channel': 'Channel',\n 'update.channelLatest': 'Stable',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Check for updates',\n 'update.checking': 'Checking…',\n 'update.current': 'Current version',\n 'update.upToDate': 'Up to date 🎉',\n 'update.available': 'New version available:',\n 'update.autoAvailable': 'Auto-check found a new version:',\n 'update.commandHint': 'Run this in a terminal to upgrade (replace web with your profile name):',\n 'update.commandHintDetected': 'Profile \"{profile}\" detected — run this in a terminal to upgrade:',\n 'update.commandHintDesktop': 'DSH Desktop detected — target profile \"{profile}\", run this in the DSH terminal to upgrade:',\n 'update.commandHintOfficialDesktop': 'Official desktop build detected (DeepSeek Harness client) — it has no CLI upgrade path: delete this plugin on the **Plugins** page, then paste the package name below into \"Add plugin\" to reinstall.',\n 'update.restartHint': 'Restart dsh web after the upgrade.',\n 'update.restartHintDesktop': 'Restart DSH Desktop after the upgrade.',\n 'update.copy': 'Copy command',\n 'update.copySpec': 'Copy package name',\n 'update.copied': 'Copied ✓',\n 'update.failed': 'Check failed — try again later.',\n 'update.retry': 'Retry',\n 'update.retryHint': 'Auto-retrying in {s}s…',\n 'update.checkedAt': 'Checked at',\n 'update.localInstall': 'This install is a local link/source checkout — the npm upgrade command may not apply; use git pull or rebuild instead.',\n 'update.conflict': 'Another window updated the settings — your local changes were not saved.',\n 'update.conflictDismiss': 'Dismiss',\n 'update.err.registry': 'Could not reach the npm registry — check your network and retry.',\n 'update.err.http': 'The npm registry returned an unexpected status code.',\n 'update.err.noTags': 'The npm registry returned no usable version tags.',\n 'update.err.invalid': 'The npm registry returned unparseable data.',\n 'update.err.networkLocal': 'Could not reach the plugin host — check your network, then refresh the page.',\n 'update.err.networkUpstream': 'The npm registry is temporarily unavailable (request timed out) — try again later.',\n 'links.title': 'Feedback & support',\n 'links.issue': 'Found a problem with the Catppuccin appearance plugin, or have an idea? Open an issue',\n 'links.star': 'Enjoying this Catppuccin appearance plugin? Star it on GitHub ⭐',\n}\n\n/** Japanese dictionary. */\nexport const ja: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin テーマ',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha の4色をワンクリックで切替。',\n 'row.off': 'システムに従う',\n 'row.helpLabel': 'Catppuccin テーマについて',\n 'row.help': 'Catppuccin コミュニティの4色: Latte(ライト)、Frappé / Macchiato / Mocha(ダーク)。選択直後に反映され、保存されます。',\n 'row.shikiStyle': 'コードハイライト',\n 'row.shikiDefault': 'デフォルト',\n 'row.shikiItalicComments': 'ソフトなコメント',\n 'row.overrides': 'カスタム上書き',\n 'row.overridesHint': '「--dsw-* 変数: 値」の形で個別トークンを上書きします。例: --dsw-static-blue-500: #89b4fa。フォーカスを外すと反映、空値で削除。',\n 'row.overridesEmpty': '上書きはまだありません。「+ 追加」で作成します。',\n 'row.overridesAdd': '追加',\n 'row.overridesRemove': 'この上書きを削除',\n 'row.overridesKey': 'トークン名',\n 'row.overridesValue': 'トークン値',\n 'flavor.latte.subtitle': 'ライト',\n 'flavor.frappe.subtitle': 'ダーク',\n 'flavor.macchiato.subtitle': 'ダーク',\n 'flavor.mocha.subtitle': 'ダーク',\n 'glass.title': 'ガラス質感',\n 'glass.description': 'トップバー・サイドバー・入力欄・ステータス行・軌跡ビューにすりガラス効果、ワンクリックで ON/OFF。',\n 'glass.helpLabel': 'ガラス質感について',\n 'glass.help': 'Catppuccin テーマの上に乗せるガラススキン: 浮遊カード(Mica)または原版レイアウト互換モード。ぼかし・曇り・背景輝度を調整でき、クリア / スタンダード / 曇りのプリセット付き。Mica はトップバーや入力欄など広い範囲をぼかすため、ストリーミング中は GPU を消費します。気になる場合は互換モードか「クリア」プリセットを。',\n 'glass.enable': 'マスタースイッチ',\n 'glass.mode': 'モード',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': '互換',\n 'glass.modeHint': 'Mica は浮遊するすりガラスカードに再構成。互換は原版レイアウトのまま素材だけガラスに(広範囲のぼかしなし=軽い)',\n 'glass.presets': 'プリセット',\n 'glass.presetClear': 'クリア',\n 'glass.presetStandard': 'スタンダード',\n 'glass.presetFrosted': '曇り',\n 'glass.blur': 'ぼかし',\n 'glass.frost': '曇り',\n 'glass.brightness': '背景の輝度',\n 'glass.brightnessHintDark': 'ダーク: 0 で純黒、50 でそのまま',\n 'glass.brightnessHintLight': 'ライト: 50 でそのまま、100 で純白',\n 'glass.reset': 'デフォルトに戻す',\n 'update.title': 'Catppuccin プラグインの更新を確認',\n 'update.description': 'npm 上の dsh-catppuccin 最新版を確認し、このインストールが最新かどうかを判断します。',\n 'update.helpLabel': '更新チェックについて',\n 'update.help': 'npm registry に本プラグインの最新版を問い合わせます。自動チェックを有効にすると起動時と6時間ごとに確認。チャンネルを beta にするとプレリリースも追跡します。',\n 'update.autoCheck': '更新を自動チェック',\n 'update.channel': 'チャンネル',\n 'update.channelLatest': '安定版',\n 'update.channelBeta': 'Beta',\n 'update.check': '更新を確認',\n 'update.checking': '確認中…',\n 'update.current': '現在のバージョン',\n 'update.upToDate': '最新です 🎉',\n 'update.available': '新しいバージョンがあります:',\n 'update.autoAvailable': '自動チェックで新しいバージョン:',\n 'update.commandHint': 'ターミナルで以下を実行してアップグレード(web をあなたの profile 名に変更):',\n 'update.commandHintDetected': 'profile「{profile}」を検出。ターミナルで以下を実行してアップグレード:',\n 'update.commandHintDesktop': 'DSH Desktop を検出。target profile「{profile}」、DSH ターミナルで以下を実行:',\n 'update.commandHintOfficialDesktop': '公式デスクトップ版(DeepSeek Harness クライアント)を検出: CLI からのアップグレード経路はありません——**プラグイン画面**で本プラグインを先に削除し、下のパッケージ名を「プラグインを追加」に貼り付けて再インストールしてください。',\n 'update.restartHint': 'アップグレード後、dsh web を再起動してください。',\n 'update.restartHintDesktop': 'アップグレード後、DSH Desktop を再起動してください。',\n 'update.copy': 'コマンドをコピー',\n 'update.copySpec': 'パッケージ名をコピー',\n 'update.copied': 'コピーしました ✓',\n 'update.failed': '確認に失敗しました。後で再試行してください。',\n 'update.retry': '再試行',\n 'update.retryHint': '{s} 秒後に自動再試行…',\n 'update.checkedAt': '確認時刻',\n 'update.localInstall': 'ローカルリンク/ソースインストールを検出しました。npm のアップグレードコマンドは使えないかもしれません。git pull か再ビルドを。',\n 'update.conflict': '別のウィンドウが設定を更新したため、ローカルの変更は保存されませんでした。',\n 'update.conflictDismiss': '閉じる',\n 'update.err.registry': 'npm registry に接続できません。ネットワークを確認して再試行してください。',\n 'update.err.http': 'npm registry が異常なステータスコードを返しました。',\n 'update.err.noTags': 'npm registry が利用可能なバージョンタグを返しませんでした。',\n 'update.err.invalid': 'npm registry が解析不能なデータを返しました。',\n 'update.err.networkLocal': 'プラグインのホストに接続できません。ネットワークを確認してページを更新してください。',\n 'update.err.networkUpstream': 'npm registry が一時的に利用できません(タイムアウト)。後で再試行してください。',\n 'links.title': 'フィードバックとサポート',\n 'links.issue': 'Catppuccin 外観プラグインの問題や提案がありますか?Issue を作成',\n 'links.star': 'この Catppuccin 外観プラグインが気に入ったら GitHub でスターを ⭐',\n}\n\n/** Korean dictionary. */\nexport const ko: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin 테마',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha 네 가지 배색, 한 번의 클릭으로 전환.',\n 'row.off': '시스템 팔로우',\n 'row.helpLabel': 'Catppuccin 테마 정보',\n 'row.help': 'Catppuccin 커뮤니티의 네 가지 배색: Latte(밝음), Frappé / Macchiato / Mocha(어두움). 선택 즉시 적용되고 저장됩니다.',\n 'row.shikiStyle': '코드 하이라이트',\n 'row.shikiDefault': '기본',\n 'row.shikiItalicComments': '부드러운 주석',\n 'row.overrides': '사용자 정의 오버라이드',\n 'row.overridesHint': '\"--dsw-* 변수: 값\" 형태로 개별 토큰을 덮어씁니다. 예: --dsw-static-blue-500: #89b4fa. 포커스를 벗어나면 적용, 빈 값은 삭제.',\n 'row.overridesEmpty': '아직 오버라이드가 없습니다. \"+ 추가\"로 만드세요.',\n 'row.overridesAdd': '추가',\n 'row.overridesRemove': '이 오버라이드 삭제',\n 'row.overridesKey': '토큰 이름',\n 'row.overridesValue': '토큰 값',\n 'flavor.latte.subtitle': '밝음',\n 'flavor.frappe.subtitle': '어두움',\n 'flavor.macchiato.subtitle': '어두움',\n 'flavor.mocha.subtitle': '어두움',\n 'glass.title': '글라스 질감',\n 'glass.description': '상단바·사이드바·입력창·통계줄·궤적 뷰에 프러스트드 글라스 효과, 원클릭 ON/OFF.',\n 'glass.helpLabel': '글라스 질감 정보',\n 'glass.help': 'Catppuccin 테마 위에 얹는 글라스 스킨: 떠 있는 카드(Mica) 또는 원본 레이아웃 호환 모드. 블러·프로스트·배경 밝기를 조절할 수 있고 클리어/스탠다드/프로스트 프리셋이 있습니다. Mica는 상단 바·입력창 등 넓은 영역을 흐리게 하므로 스트리밍 중 GPU를 더 씁니다. 부담되면 호환 모드나 「클리어」 프리셋을 쓰세요.',\n 'glass.enable': '마스터 스위치',\n 'glass.mode': '모드',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': '호환',\n 'glass.modeHint': 'Mica는 UI를 떠 있는 프러스트드 카드로 변경. 호환은 원본 레이아웃을 유지하고 재질만 글라스로 (넓은 영역 블러 없음 = 더 가벼움)',\n 'glass.presets': '프리셋',\n 'glass.presetClear': '클리어',\n 'glass.presetStandard': '스탠다드',\n 'glass.presetFrosted': '프로스트',\n 'glass.blur': '블러',\n 'glass.frost': '프로스트',\n 'glass.brightness': '배경 밝기',\n 'glass.brightnessHintDark': '다크 모드: 0이면 순수 검정, 50이면 그대로',\n 'glass.brightnessHintLight': '라이트 모드: 50이면 그대로, 100이면 순수 흰색',\n 'glass.reset': '기본값으로 되돌리기',\n 'update.title': 'Catppuccin 플러그인 업데이트 확인',\n 'update.description': 'npm의 최신 dsh-catppuccin 버전을 확인하고 현재 설치가 최신인지 판단합니다.',\n 'update.helpLabel': '업데이트 확인 정보',\n 'update.help': 'npm registry에서 이 플러그인의 최신 버전을 조회합니다. 자동 확인을 켜면 시작 시와 6시간마다 확인합니다. 채널을 beta로 하면 프리릴리스도 추적합니다.',\n 'update.autoCheck': '업데이트 자동 확인',\n 'update.channel': '채널',\n 'update.channelLatest': '안정판',\n 'update.channelBeta': 'Beta',\n 'update.check': '업데이트 확인',\n 'update.checking': '확인 중…',\n 'update.current': '현재 버전',\n 'update.upToDate': '최신 버전입니다 🎉',\n 'update.available': '새 버전 발견:',\n 'update.autoAvailable': '자동 확인으로 새 버전 발견:',\n 'update.commandHint': '터미널에서 다음을 실행해 업그레이드하세요 (web을 당신의 profile 이름으로 교체):',\n 'update.commandHintDetected': 'profile「{profile}」을 감지했습니다. 터미널에서 다음을 실행하세요:',\n 'update.commandHintDesktop': 'DSH Desktop 감지. 대상 profile「{profile}」, DSH 터미널에서 다음을 실행하세요:',\n 'update.commandHintOfficialDesktop': '공식 데스크톱 버전(DeepSeek Harness 클라이언트)을 감지했습니다: CLI 업그레이드 경로가 없습니다——**플러그인 화면**에서 이 플러그인을 먼저 삭제한 뒤 아래 패키지 이름을 「플러그인 추가」에 붙여 다시 설치하세요.',\n 'update.restartHint': '업그레이드 후 dsh web을 재시작하세요.',\n 'update.restartHintDesktop': '업그레이드 후 DSH Desktop을 재시작하세요.',\n 'update.copy': '명령 복사',\n 'update.copySpec': '패키지 이름 복사',\n 'update.copied': '복사됨 ✓',\n 'update.failed': '확인 실패. 잠시 후 다시 시도하세요.',\n 'update.retry': '다시 시도',\n 'update.retryHint': '{s}초 후 자동 재시도…',\n 'update.checkedAt': '확인 시각',\n 'update.localInstall': '로컬 링크/소스 설치를 감지했습니다. npm 업그레이드 명령이 맞지 않을 수 있으니 git pull 또는 재빌드를 사용하세요.',\n 'update.conflict': '다른 창에서 설정을 업데이트했습니다. 로컬 변경 사항은 저장되지 않았습니다.',\n 'update.conflictDismiss': '닫기',\n 'update.err.registry': 'npm registry에 연결할 수 없습니다. 네트워크를 확인하고 다시 시도하세요.',\n 'update.err.http': 'npm registry가 비정상 상태 코드를 반환했습니다.',\n 'update.err.noTags': 'npm registry가 사용 가능한 버전 태그를 반환하지 않았습니다.',\n 'update.err.invalid': 'npm registry가 해석할 수 없는 데이터를 반환했습니다.',\n 'update.err.networkLocal': '플러그인 호스트에 연결할 수 없습니다. 네트워크를 확인한 뒤 페이지를 새로고침하세요.',\n 'update.err.networkUpstream': 'npm registry를 일시적으로 사용할 수 없습니다(시간 초과). 잠시 후 다시 시도하세요.',\n 'links.title': '피드백 및 지원',\n 'links.issue': 'Catppuccin 테마 플러그인에 문제나 제안이 있나요? 이슈를 남겨 주세요',\n 'links.star': '이 Catppuccin 테마 플러그인이 마음에 드셨다면 GitHub에서 스타를 ⭐',\n}\n\n/** Spanish dictionary. */\nexport const es: Record<keyof typeof zh, string> = {\n 'row.title': 'Tema Catppuccin',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, a un clic.',\n 'row.off': 'Seguir al sistema',\n 'row.helpLabel': 'Acerca del tema Catppuccin',\n 'row.help': 'Cuatro paletas de la comunidad Catppuccin: Latte (claro), Frappé / Macchiato / Mocha (oscuro). Se aplican al instante y se guardan.',\n 'row.shikiStyle': 'Estilo de resaltado',\n 'row.shikiDefault': 'Predeterminado',\n 'row.shikiItalicComments': 'Comentarios suaves',\n 'row.overrides': 'Anulaciones personalizadas',\n 'row.overridesHint': 'Anula tokens individuales como \"variable --dsw-*: valor\", p. ej. --dsw-static-blue-500: #89b4fa. Se aplica al salir del campo; un valor vacío elimina la entrada.',\n 'row.overridesEmpty': 'Aún no hay anulaciones. Pulsa \"+ Añadir\" para crear una.',\n 'row.overridesAdd': 'Añadir',\n 'row.overridesRemove': 'Eliminar esta anulación',\n 'row.overridesKey': 'Nombre del token',\n 'row.overridesValue': 'Valor del token',\n 'flavor.latte.subtitle': 'Claro',\n 'flavor.frappe.subtitle': 'Oscuro',\n 'flavor.macchiato.subtitle': 'Oscuro',\n 'flavor.mocha.subtitle': 'Oscuro',\n 'glass.title': 'Vidrio esmerilado',\n 'glass.description': 'Efecto de vidrio esmerilado en barra superior, barra lateral, redactor, línea de estadísticas y vista de trayectoria: un clic para activarlo.',\n 'glass.helpLabel': 'Acerca del vidrio esmerilado',\n 'glass.help': 'Una piel de vidrio esmerilado sobre el tema Catppuccin: tarjetas flotantes (Mica) o el diseño original con material de vidrio (Compatibilidad). Desenfoque, escarcha y brillo del fondo ajustables, con preajustes Claro / Estándar / Escarchado. Mica desenfoca zonas grandes (barra superior, cuadro de texto), así que consume GPU mientras llega la respuesta: usa Compatibilidad o el preajuste Claro si te importa.',\n 'glass.enable': 'Interruptor general',\n 'glass.mode': 'Modo',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Compatibilidad',\n 'glass.modeHint': 'Mica convierte la interfaz en tarjetas flotantes esmeriladas; Compatibilidad mantiene el diseño original y solo cambia el material (sin desenfoque de zonas grandes: más ligero)',\n 'glass.presets': 'Preajustes',\n 'glass.presetClear': 'Claro',\n 'glass.presetStandard': 'Estándar',\n 'glass.presetFrosted': 'Escarchado',\n 'glass.blur': 'Desenfoque del vidrio',\n 'glass.frost': 'Escarcha',\n 'glass.brightness': 'Brillo del fondo',\n 'glass.brightnessHintDark': 'Modo oscuro: 0 atenúa a negro puro, 50 sin cambios',\n 'glass.brightnessHintLight': 'Modo claro: 50 sin cambios, 100 aclara hasta blanco puro',\n 'glass.reset': 'Restablecer valores',\n 'update.title': 'Comprobar actualizaciones del plugin Catppuccin',\n 'update.description': 'Comprueba en npm la última versión de dsh-catppuccin y si esta instalación está al día.',\n 'update.helpLabel': 'Acerca de la comprobación de actualizaciones',\n 'update.help': 'Consulta a npm registry la versión más reciente de este plugin. Con la comprobación automática activada, se consulta al inicio y cada 6 horas; el canal Beta también persigue prelanzamientos.',\n 'update.autoCheck': 'Comprobación automática',\n 'update.channel': 'Canal',\n 'update.channelLatest': 'Estable',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Comprobar actualizaciones',\n 'update.checking': 'Comprobando…',\n 'update.current': 'Versión actual',\n 'update.upToDate': 'Ya está actualizado 🎉',\n 'update.available': 'Nueva versión disponible:',\n 'update.autoAvailable': 'La comprobación automática encontró una versión nueva:',\n 'update.commandHint': 'Ejecuta esto en una terminal para actualizar (sustituye web por el nombre de tu profile):',\n 'update.commandHintDetected': 'Profile \"{profile}\" detectado: ejecuta esto en una terminal para actualizar:',\n 'update.commandHintDesktop': 'DSH Desktop detectado: profile objetivo \"{profile}\", ejecuta esto en la terminal de DSH:',\n 'update.commandHintOfficialDesktop': 'Se detectó la versión oficial de escritorio (cliente DeepSeek Harness): no tiene ruta de actualización por CLI; elimina este plugin en la página **Plugins** y pega el nombre del paquete de abajo en «Añadir plugin» para reinstalarlo.',\n 'update.restartHint': 'Reinicia dsh web tras la actualización.',\n 'update.restartHintDesktop': 'Reinicia DSH Desktop tras la actualización.',\n 'update.copy': 'Copiar comando',\n 'update.copySpec': 'Copiar nombre del paquete',\n 'update.copied': 'Copiado ✓',\n 'update.failed': 'Error al comprobar; inténtalo de nuevo más tarde.',\n 'update.retry': 'Reintentar',\n 'update.retryHint': 'Reintento automático en {s}s…',\n 'update.checkedAt': 'Comprobado a las',\n 'update.localInstall': 'Instalación local por enlace/código detectada: el comando npm puede no servir; usa git pull o reconstruye.',\n 'update.conflict': 'Otra ventana actualizó los ajustes: tus cambios locales no se guardaron.',\n 'update.conflictDismiss': 'Descartar',\n 'update.err.registry': 'No se pudo conectar con npm registry: revisa tu red e inténtalo de nuevo.',\n 'update.err.http': 'npm registry devolvió un código de estado inesperado.',\n 'update.err.noTags': 'npm registry no devolvió etiquetas de versión utilizables.',\n 'update.err.invalid': 'npm registry devolvió datos no analizables.',\n 'update.err.networkLocal': 'No se pudo conectar con el host del plugin: revisa tu red y recarga la página.',\n 'update.err.networkUpstream': 'npm registry no está disponible temporalmente (tiempo de espera agotado); inténtalo más tarde.',\n 'links.title': 'Comentarios y soporte',\n 'links.issue': '¿Un problema o una idea con el plugin de apariencia Catppuccin? Abre un issue',\n 'links.star': '¿Te gusta este plugin de apariencia Catppuccin? Dale una estrella en GitHub ⭐',\n}\n\n/** French dictionary. */\nexport const fr: Record<keyof typeof zh, string> = {\n 'row.title': 'Thème Catppuccin',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, en un clic.',\n 'row.off': 'Suivre le système',\n 'row.helpLabel': 'À propos du thème Catppuccin',\n 'row.help': 'Quatre palettes de la communauté Catppuccin : Latte (clair), Frappé / Macchiato / Mocha (sombre). Application immédiate et persistante.',\n 'row.shikiStyle': 'Style de coloration',\n 'row.shikiDefault': 'Par défaut',\n 'row.shikiItalicComments': 'Commentaires doux',\n 'row.overrides': 'Remplacements personnalisés',\n 'row.overridesHint': 'Remplace des jetons individuellement sous la forme « variable --dsw-*: valeur », ex. --dsw-static-blue-500: #89b4fa. Application à la sortie du champ ; une valeur vide supprime l\\'entrée.',\n 'row.overridesEmpty': 'Aucun remplacement pour l\\'instant. Cliquez sur « + Ajouter » pour en créer un.',\n 'row.overridesAdd': 'Ajouter',\n 'row.overridesRemove': 'Supprimer ce remplacement',\n 'row.overridesKey': 'Nom du jeton',\n 'row.overridesValue': 'Valeur du jeton',\n 'flavor.latte.subtitle': 'Clair',\n 'flavor.frappe.subtitle': 'Sombre',\n 'flavor.macchiato.subtitle': 'Sombre',\n 'flavor.mocha.subtitle': 'Sombre',\n 'glass.title': 'Verre dépoli',\n 'glass.description': 'Effet verre dépoli sur la barre du haut, la barre latérale, le rédacteur, la ligne de stats et la vue de trajectoire — un clic pour activer.',\n 'glass.helpLabel': 'À propos du verre dépoli',\n 'glass.help': 'Une peau en verre dépoli par-dessus le thème Catppuccin : cartes flottantes (Mica) ou mise en page d\\'origine avec un matériau verre (Compatibilité). Flou, givre et luminosité du fond réglables, avec les préréglages Clair / Standard / Givré. Mica floute de grandes zones (barre supérieure, champ de saisie) : cela consomme le GPU pendant la génération — préférez Compatibilité ou le préréglage Clair si c\\'est gênant.',\n 'glass.enable': 'Interrupteur principal',\n 'glass.mode': 'Mode',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Compatibilité',\n 'glass.modeHint': 'Mica transforme l\\'interface en cartes flottantes dépoli ; Compatibilité garde la mise en page d\\'origine et change seulement le matériau (pas de flou sur de grandes zones : plus léger)',\n 'glass.presets': 'Préréglages',\n 'glass.presetClear': 'Clair',\n 'glass.presetStandard': 'Standard',\n 'glass.presetFrosted': 'Givré',\n 'glass.blur': 'Flou du verre',\n 'glass.frost': 'Givre',\n 'glass.brightness': 'Luminosité du fond',\n 'glass.brightnessHintDark': 'Mode sombre : 0 atténue vers le noir pur, 50 inchangé',\n 'glass.brightnessHintLight': 'Mode clair : 50 inchangé, 100 éclaircit vers le blanc pur',\n 'glass.reset': 'Restaurer les valeurs',\n 'update.title': 'Vérifier les mises à jour du plugin Catppuccin',\n 'update.description': 'Interroge npm pour la dernière version de dsh-catppuccin et indique si cette installation est à jour.',\n 'update.helpLabel': 'À propos de la vérification des mises à jour',\n 'update.help': 'Interroge npm registry pour la dernière version de ce plugin. Avec la vérification automatique active, un contrôle a lieu au démarrage puis toutes les 6 heures ; le canal Beta suit aussi les préversions.',\n 'update.autoCheck': 'Vérification automatique',\n 'update.channel': 'Canal',\n 'update.channelLatest': 'Stable',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Vérifier les mises à jour',\n 'update.checking': 'Vérification…',\n 'update.current': 'Version actuelle',\n 'update.upToDate': 'À jour 🎉',\n 'update.available': 'Nouvelle version disponible :',\n 'update.autoAvailable': 'La vérification automatique a trouvé une nouvelle version :',\n 'update.commandHint': 'Exécutez ceci dans un terminal pour mettre à jour (remplacez web par le nom de votre profile) :',\n 'update.commandHintDetected': 'Profile « {profile} » détecté — exécutez ceci dans un terminal :',\n 'update.commandHintDesktop': 'DSH Desktop détecté — profile cible « {profile} », exécutez ceci dans le terminal DSH :',\n 'update.commandHintOfficialDesktop': 'Version bureau officielle détectée (client DeepSeek Harness) : aucune mise à jour en ligne de commande — supprimez ce plugin dans la page **Plugins**, puis collez le nom du paquet ci-dessous dans « Ajouter un plugin » pour le réinstaller.',\n 'update.restartHint': 'Redémarrez dsh web après la mise à jour.',\n 'update.restartHintDesktop': 'Redémarrez DSH Desktop après la mise à jour.',\n 'update.copy': 'Copier la commande',\n 'update.copySpec': 'Copier le nom du paquet',\n 'update.copied': 'Copié ✓',\n 'update.failed': 'Échec de la vérification — réessayez plus tard.',\n 'update.retry': 'Réessayer',\n 'update.retryHint': 'Nouvel essai automatique dans {s}s…',\n 'update.checkedAt': 'Vérifié à',\n 'update.localInstall': 'Installation locale par lien/code source détectée : la commande npm peut ne pas convenir ; utilisez git pull ou reconstruisez.',\n 'update.conflict': 'Une autre fenêtre a mis à jour les réglages — vos modifications locales n\\'ont pas été enregistrées.',\n 'update.conflictDismiss': 'Ignorer',\n 'update.err.registry': 'Impossible de joindre npm registry — vérifiez votre réseau et réessayez.',\n 'update.err.http': 'npm registry a renvoyé un code de statut inattendu.',\n 'update.err.noTags': 'npm registry n\\'a renvoyé aucune étiquette de version utile.',\n 'update.err.invalid': 'npm registry a renvoyé des données non analysables.',\n 'update.err.networkLocal': 'Impossible de joindre l\\'hôte du plugin — vérifiez votre réseau puis rechargez la page.',\n 'update.err.networkUpstream': 'npm registry est temporairement indisponible (délai dépassé) — réessayez plus tard.',\n 'links.title': 'Retours et support',\n 'links.issue': 'Un problème ou une idée pour le plugin d\\'apparence Catppuccin ? Ouvrez une issue',\n 'links.star': 'Vous aimez ce plugin d\\'apparence Catppuccin ? Laissez une Star sur GitHub ⭐',\n}\n\n/** German dictionary. */\nexport const de: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin-Design',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, mit einem Klick.',\n 'row.off': 'System folgen',\n 'row.helpLabel': 'Über das Catppuccin-Design',\n 'row.help': 'Vier Paletten der Catppuccin-Community: Latte (hell), Frappé / Macchiato / Mocha (dunkel). Wirkt sofort und wird gespeichert.',\n 'row.shikiStyle': 'Code-Hervorhebung',\n 'row.shikiDefault': 'Standard',\n 'row.shikiItalicComments': 'Sanfte Kommentare',\n 'row.overrides': 'Benutzerdefinierte Überschreibungen',\n 'row.overridesHint': 'Einzelne Tokens als „--dsw-*-Variable: Wert“ überschreiben, z. B. --dsw-static-blue-500: #89b4fa. Wirkt beim Verlassen des Feldes; ein leerer Wert löscht den Eintrag.',\n 'row.overridesEmpty': 'Noch keine Überschreibungen. Klicken Sie auf „+ Hinzufügen“, um eine anzulegen.',\n 'row.overridesAdd': 'Hinzufügen',\n 'row.overridesRemove': 'Diese Überschreibung entfernen',\n 'row.overridesKey': 'Token-Name',\n 'row.overridesValue': 'Token-Wert',\n 'flavor.latte.subtitle': 'Hell',\n 'flavor.frappe.subtitle': 'Dunkel',\n 'flavor.macchiato.subtitle': 'Dunkel',\n 'flavor.mocha.subtitle': 'Dunkel',\n 'glass.title': 'Glasmorphismus',\n 'glass.description': 'Milchglas-Effekt für obere Leiste, Seitenleiste, Eingabe, Statistikzeile und Trajektorienansicht – ein Klick an/aus.',\n 'glass.helpLabel': 'Über Glasmorphismus',\n 'glass.help': 'Eine Milchglas-Haut über dem Catppuccin-Design: schwebende Karten (Mica) oder das Original-Layout mit Glas-Material (Kompatibilität). Unschärfe, Frost und Hintergrundhelligkeit einstellbar, mit den Voreinstellungen Klar / Standard / Frostig. Mica verwischt große Flächen (Kopfleiste, Eingabefeld) und kostet daher GPU, während die Antwort streamt — nimm Kompatibilität oder die Voreinstellung Klar, wenn das stört.',\n 'glass.enable': 'Hauptschalter',\n 'glass.mode': 'Modus',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Kompatibilität',\n 'glass.modeHint': 'Mica verwandelt die Oberfläche in schwebende Milchglas-Karten; Kompatibilität behält das Original-Layout und tauscht nur das Material (keine großen Unschärfeflächen — die leichtere Option)',\n 'glass.presets': 'Voreinstellungen',\n 'glass.presetClear': 'Klar',\n 'glass.presetStandard': 'Standard',\n 'glass.presetFrosted': 'Frostig',\n 'glass.blur': 'Glas-Unschärfe',\n 'glass.frost': 'Frost',\n 'glass.brightness': 'Hintergrundhelligkeit',\n 'glass.brightnessHintDark': 'Dunkelmodus: 0 verdunkelt zu reinem Schwarz, 50 unverändert',\n 'glass.brightnessHintLight': 'Hellmodus: 50 unverändert, 100 hellt zu reinem Weiß auf',\n 'glass.reset': 'Standardwerte wiederherstellen',\n 'update.title': 'Catppuccin-Plugin-Updates prüfen',\n 'update.description': 'Prüft die neueste dsh-catppuccin-Version auf npm und ob diese Installation aktuell ist.',\n 'update.helpLabel': 'Über die Update-Prüfung',\n 'update.help': 'Fragt npm registry nach der neuesten Version dieses Plugins. Bei aktivierter automatischer Prüfung läuft ein Check beim Start und alle 6 Stunden; der Beta-Kanal verfolgt auch Vorabversionen.',\n 'update.autoCheck': 'Automatisch prüfen',\n 'update.channel': 'Kanal',\n 'update.channelLatest': 'Stabil',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Auf Updates prüfen',\n 'update.checking': 'Prüfe…',\n 'update.current': 'Aktuelle Version',\n 'update.upToDate': 'Aktuell 🎉',\n 'update.available': 'Neue Version verfügbar:',\n 'update.autoAvailable': 'Automatische Prüfung fand eine neue Version:',\n 'update.commandHint': 'Führen Sie dies in einem Terminal aus (ersetzen Sie web durch Ihren Profile-Namen):',\n 'update.commandHintDetected': 'Profile „{profile}“ erkannt – führen Sie dies in einem Terminal aus:',\n 'update.commandHintDesktop': 'DSH Desktop erkannt – Ziel-Profile „{profile}“, führen Sie dies im DSH-Terminal aus:',\n 'update.commandHintOfficialDesktop': 'Offizielle Desktop-Version erkannt (DeepSeek Harness-Client): Es gibt keinen CLI-Upgradepfad – löschen Sie dieses Plugin auf der Seite **Plugins** und fügen Sie den Paketnamen unten in „Plugin hinzufügen“ ein, um es neu zu installieren.',\n 'update.restartHint': 'Starten Sie dsh web nach dem Update neu.',\n 'update.restartHintDesktop': 'Starten Sie DSH Desktop nach dem Update neu.',\n 'update.copy': 'Befehl kopieren',\n 'update.copySpec': 'Paketnamen kopieren',\n 'update.copied': 'Kopiert ✓',\n 'update.failed': 'Prüfung fehlgeschlagen – versuchen Sie es später erneut.',\n 'update.retry': 'Erneut versuchen',\n 'update.retryHint': 'Automatischer Versuch in {s}s…',\n 'update.checkedAt': 'Geprüft um',\n 'update.localInstall': 'Lokale Link-/Quellcode-Installation erkannt: Der npm-Befehl passt möglicherweise nicht; verwenden Sie git pull oder einen Neubuild.',\n 'update.conflict': 'Ein anderes Fenster hat die Einstellungen aktualisiert – Ihre lokalen Änderungen wurden nicht gespeichert.',\n 'update.conflictDismiss': 'Schließen',\n 'update.err.registry': 'npm registry nicht erreichbar – prüfen Sie Ihre Verbindung und versuchen Sie es erneut.',\n 'update.err.http': 'npm registry lieferte einen unerwarteten Statuscode.',\n 'update.err.noTags': 'npm registry lieferte keine brauchbaren Versions-Tags.',\n 'update.err.invalid': 'npm registry lieferte nicht analysierbare Daten.',\n 'update.err.networkLocal': 'Plugin-Host nicht erreichbar – prüfen Sie Ihre Verbindung und laden Sie die Seite neu.',\n 'update.err.networkUpstream': 'npm registry ist vorübergehend nicht verfügbar (Zeitüberschreitung) – versuchen Sie es später erneut.',\n 'links.title': 'Feedback & Support',\n 'links.issue': 'Problem oder Idee zum Catppuccin-Design-Plugin? Eröffnen Sie ein Issue',\n 'links.star': 'Gefällt Ihnen dieses Catppuccin-Design-Plugin? Geben Sie ihm einen Star auf GitHub ⭐',\n}\n\n/** Key union of the Catppuccin dictionaries. */\nexport type CatppuccinKey = keyof typeof zh","/**\n * AUTO-GENERATED by scripts/generate-palettes.mjs — do not edit by hand.\n * Catppuccin token tables for the DeepSeek Harness web GUI.\n * Source palette: https://github.com/catppuccin/catppuccin (palette.json v1.8.0).\n * // UPSTREAM_PIN: 639ed015397290b3745d163aafe02ffee4aa3f84\n * Each flavour carries a flat dictionary of every --dsw-static-*,\n * --dsw-alias-* and --dsw-specific-* token the official theme stylesheet\n * declares, plus the --dsw-* tokens outside those families (0.2.0's\n * --dsw-menu-surface-fill). Alias/specific entries keep their var() references\n * so the static overrides below flow through automatically; literal (non-var)\n * entries are remapped to Catppuccin colours — see aliasLiteralOverrides.\n */\nexport type CatppuccinFlavorId = 'latte' | 'frappe' | 'macchiato' | 'mocha'\nexport interface CatppuccinFlavorInfo {\n /** Theme id registered into ThemeRuntime. */\n themeId: string\n /** Base color scheme this flavour builds on. */\n colorScheme: 'light' | 'dark'\n /** Display label. */\n label: string\n /** Accent colour for the settings row swatch. */\n accent: string\n /** Token dictionary (--dsw-* names). */\n tokens: Record<string, string>\n}\n\nexport const CATPPUCCIN_LATTE: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-latte',\n colorScheme: 'light',\n label: 'Latte',\n accent: '#1e66f5',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #fe640b 20%, #eff1f5)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #fe640b 70%, #eff1f5)\",\n \"--dsw-static-amber-500\": \"#fe640b\",\n \"--dsw-static-amber-600\": \"#fe640b\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #fe640b 32%, #eff1f5)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #1e66f5 22%, #eff1f5)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #1e66f5 48%, #eff1f5)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #1e66f5 65%, #eff1f5)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-blue-500\": \"#1e66f5\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #1e66f5 8%, #eff1f5)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #1e66f5 12%, #eff1f5)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #1e66f5 16%, #eff1f5)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #1e66f5 50%, #eff1f5)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #1e66f5 30%, #4c4f69)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #1e66f5 26%, #eff1f5)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #1e66f5 22%, #eff1f5)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #1e66f5 34%, #eff1f5)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #1e66f5 48%, #eff1f5)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #1e66f5 65%, #eff1f5)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-deepseek-500\": \"#1e66f5\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #1e66f5 8%, #eff1f5)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #1e66f5 66%, #eff1f5)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #1e66f5 50%, #eff1f5)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #1e66f5 38%, #eff1f5)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #40a02b 18%, #eff1f5)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #40a02b 80%, #eff1f5)\",\n \"--dsw-static-green-500\": \"#40a02b\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #40a02b 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #40a02b 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #40a02b 30%, #eff1f5)\",\n \"--dsw-static-neutral-00\": \"#eff1f5\",\n \"--dsw-static-neutral-1000\": \"#4c4f69\",\n \"--dsw-static-neutral-100\": \"#bcc0cc\",\n \"--dsw-static-neutral-150\": \"#acb0be\",\n \"--dsw-static-neutral-200\": \"#9ca0b0\",\n \"--dsw-static-neutral-250\": \"#9ca0b0\",\n \"--dsw-static-neutral-300\": \"#8c8fa1\",\n \"--dsw-static-neutral-400\": \"#7c7f93\",\n \"--dsw-static-neutral-500\": \"#6c6f85\",\n \"--dsw-static-neutral-50\": \"#e6e9ef\",\n \"--dsw-static-neutral-550\": \"#6c6f85\",\n \"--dsw-static-neutral-600\": \"#5c5f77\",\n \"--dsw-static-neutral-700\": \"#5c5f77\",\n \"--dsw-static-neutral-800\": \"#4c4f69\",\n \"--dsw-static-neutral-850\": \"#4c4f69\",\n \"--dsw-static-neutral-900\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-00\": \"#eff1f5\",\n \"--dsw-static-neutral-bluish-1000\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-100\": \"#bcc0cc\",\n \"--dsw-static-neutral-bluish-150\": \"#acb0be\",\n \"--dsw-static-neutral-bluish-200\": \"#9ca0b0\",\n \"--dsw-static-neutral-bluish-300\": \"#8c8fa1\",\n \"--dsw-static-neutral-bluish-400\": \"#7c7f93\",\n \"--dsw-static-neutral-bluish-500\": \"#6c6f85\",\n \"--dsw-static-neutral-bluish-50\": \"#e6e9ef\",\n \"--dsw-static-neutral-bluish-600\": \"#5c5f77\",\n \"--dsw-static-neutral-bluish-60\": \"#e6e9ef\",\n \"--dsw-static-neutral-bluish-700\": \"#5c5f77\",\n \"--dsw-static-neutral-bluish-750\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-75\": \"#ccd0da\",\n \"--dsw-static-neutral-bluish-800\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-850\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-875\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-900\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-950\": \"#4c4f69\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #d20f39 20%, #eff1f5)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #d20f39 70%, #eff1f5)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #db5371 12%, transparent)\",\n \"--dsw-static-red-500\": \"#d20f39\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #d20f39 10%, #eff1f5)\",\n \"--dsw-static-red-600\": \"#d20f39\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #d20f39 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #d20f39 34%, #eff1f5)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.24)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.12)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(255, 255, 255, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(0, 0, 0, 0.04)\",\n \"--dsw-alias-border-inverted2\": \"rgba(0, 0, 0, 0)\",\n \"--dsw-alias-border-inverted\": \"rgba(0, 0, 0, 0)\",\n \"--dsw-alias-border-l1\": \"rgba(0, 0, 0, 0.04)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(0, 0, 0, 0.1)\",\n \"--dsw-alias-border-l2\": \"rgba(0, 0, 0, 0.1)\",\n \"--dsw-alias-border-l3\": \"rgba(0, 0, 0, 0.12)\",\n \"--dsw-alias-border-l4\": \"rgba(0, 0, 0, 0.16)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#1e66f5\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-500)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(38, 49, 72, 0.1)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(38, 49, 72, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(236, 19, 19, 0.05)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(38, 49, 72, 0.06)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-500) 70%, var(--dsw-static-blue-950))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-deepseek-500) 30%, var(--dsw-static-blue-950))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-blue-900)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-1000) 30%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-50)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-200)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-200)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-300)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-300)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-100)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a08)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-600-a08)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a08)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 4%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-600-a08)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 4%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-600)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-300)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-100)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-100)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-markdown-code-block)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-deepseek-200)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-deepseek-50)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-deepseek-100)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 58%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_FRAPPE: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-frappe',\n colorScheme: 'dark',\n label: 'Frappé',\n accent: '#8caaee',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #ef9f76 20%, #303446)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #ef9f76 70%, #303446)\",\n \"--dsw-static-amber-500\": \"#ef9f76\",\n \"--dsw-static-amber-600\": \"#ef9f76\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #ef9f76 18%, #232634)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #8caaee 24%, #303446)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #8caaee 50%, #303446)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #8caaee 66%, #303446)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-blue-500\": \"#8caaee\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #8caaee 10%, #303446)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #8caaee 14%, #303446)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #8caaee 18%, #303446)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #8caaee 18%, #232634)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #8caaee 14%, #232634)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #8caaee 10%, #232634)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #8caaee 24%, #303446)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #8caaee 36%, #303446)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #8caaee 50%, #303446)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #8caaee 66%, #303446)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-deepseek-500\": \"#8caaee\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #8caaee 10%, #303446)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #8caaee 68%, #303446)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #8caaee 18%, #232634)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #8caaee 14%, #232634)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #a6d189 18%, #303446)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #a6d189 80%, #303446)\",\n \"--dsw-static-green-500\": \"#a6d189\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #a6d189 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #a6d189 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #a6d189 18%, #232634)\",\n \"--dsw-static-neutral-00\": \"#c6d0f5\",\n \"--dsw-static-neutral-1000\": \"#232634\",\n \"--dsw-static-neutral-100\": \"#a5adce\",\n \"--dsw-static-neutral-150\": \"#a5adce\",\n \"--dsw-static-neutral-200\": \"#949cbb\",\n \"--dsw-static-neutral-250\": \"#949cbb\",\n \"--dsw-static-neutral-300\": \"#838ba7\",\n \"--dsw-static-neutral-400\": \"#737994\",\n \"--dsw-static-neutral-500\": \"#626880\",\n \"--dsw-static-neutral-50\": \"#c6d0f5\",\n \"--dsw-static-neutral-550\": \"#51576d\",\n \"--dsw-static-neutral-600\": \"#51576d\",\n \"--dsw-static-neutral-700\": \"#414559\",\n \"--dsw-static-neutral-800\": \"#414559\",\n \"--dsw-static-neutral-850\": \"#303446\",\n \"--dsw-static-neutral-900\": \"#292c3c\",\n \"--dsw-static-neutral-bluish-00\": \"#c6d0f5\",\n \"--dsw-static-neutral-bluish-1000\": \"#232634\",\n \"--dsw-static-neutral-bluish-100\": \"#a5adce\",\n \"--dsw-static-neutral-bluish-150\": \"#a5adce\",\n \"--dsw-static-neutral-bluish-200\": \"#949cbb\",\n \"--dsw-static-neutral-bluish-300\": \"#838ba7\",\n \"--dsw-static-neutral-bluish-400\": \"#737994\",\n \"--dsw-static-neutral-bluish-500\": \"#626880\",\n \"--dsw-static-neutral-bluish-50\": \"#c6d0f5\",\n \"--dsw-static-neutral-bluish-600\": \"#51576d\",\n \"--dsw-static-neutral-bluish-60\": \"#b5bfe2\",\n \"--dsw-static-neutral-bluish-700\": \"#414559\",\n \"--dsw-static-neutral-bluish-750\": \"#414559\",\n \"--dsw-static-neutral-bluish-75\": \"#b5bfe2\",\n \"--dsw-static-neutral-bluish-800\": \"#414559\",\n \"--dsw-static-neutral-bluish-850\": \"#303446\",\n \"--dsw-static-neutral-bluish-875\": \"#292c3c\",\n \"--dsw-static-neutral-bluish-900\": \"#292c3c\",\n \"--dsw-static-neutral-bluish-950\": \"#232634\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #e78284 20%, #303446)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #e78284 70%, #303446)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #b06b71 12%, transparent)\",\n \"--dsw-static-red-500\": \"#e78284\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #e78284 10%, #303446)\",\n \"--dsw-static-red-600\": \"#e78284\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #e78284 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #e78284 34%, #303446)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-875)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.5)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.2)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(39, 39, 48, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-850)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted2\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l1\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2\": \"rgba(255, 255, 255, 0.12)\",\n \"--dsw-alias-border-l3\": \"rgba(255, 255, 255, 0.16)\",\n \"--dsw-alias-border-l4\": \"rgba(255, 255, 255, 0.2)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#8caaee\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(255, 255, 255, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(255, 255, 255, 0.24)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(242, 90, 90, 0.15)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-450) 55%, var(--dsw-static-neutral-bluish-400))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-blue-300) 65%, var(--dsw-static-deepseek-400))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-00) 45%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-alias-label-primary-dimmed)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-800)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-700)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-550)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-800)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-900)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-900)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-active)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 45%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_MACCHIATO: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-macchiato',\n colorScheme: 'dark',\n label: 'Macchiato',\n accent: '#8aadf4',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #f5a97f 20%, #24273a)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #f5a97f 70%, #24273a)\",\n \"--dsw-static-amber-500\": \"#f5a97f\",\n \"--dsw-static-amber-600\": \"#f5a97f\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #f5a97f 18%, #181926)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #8aadf4 24%, #24273a)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #8aadf4 50%, #24273a)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #8aadf4 66%, #24273a)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-blue-500\": \"#8aadf4\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #8aadf4 10%, #24273a)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #8aadf4 14%, #24273a)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #8aadf4 18%, #24273a)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #8aadf4 18%, #181926)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #8aadf4 14%, #181926)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #8aadf4 10%, #181926)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #8aadf4 24%, #24273a)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #8aadf4 36%, #24273a)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #8aadf4 50%, #24273a)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #8aadf4 66%, #24273a)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-deepseek-500\": \"#8aadf4\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #8aadf4 10%, #24273a)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #8aadf4 68%, #24273a)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #8aadf4 18%, #181926)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #8aadf4 14%, #181926)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #a6da95 18%, #24273a)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #a6da95 80%, #24273a)\",\n \"--dsw-static-green-500\": \"#a6da95\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #a6da95 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #a6da95 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #a6da95 18%, #181926)\",\n \"--dsw-static-neutral-00\": \"#cad3f5\",\n \"--dsw-static-neutral-1000\": \"#181926\",\n \"--dsw-static-neutral-100\": \"#a5adcb\",\n \"--dsw-static-neutral-150\": \"#a5adcb\",\n \"--dsw-static-neutral-200\": \"#939ab7\",\n \"--dsw-static-neutral-250\": \"#939ab7\",\n \"--dsw-static-neutral-300\": \"#8087a2\",\n \"--dsw-static-neutral-400\": \"#6e738d\",\n \"--dsw-static-neutral-500\": \"#5b6078\",\n \"--dsw-static-neutral-50\": \"#cad3f5\",\n \"--dsw-static-neutral-550\": \"#494d64\",\n \"--dsw-static-neutral-600\": \"#494d64\",\n \"--dsw-static-neutral-700\": \"#363a4f\",\n \"--dsw-static-neutral-800\": \"#363a4f\",\n \"--dsw-static-neutral-850\": \"#24273a\",\n \"--dsw-static-neutral-900\": \"#1e2030\",\n \"--dsw-static-neutral-bluish-00\": \"#cad3f5\",\n \"--dsw-static-neutral-bluish-1000\": \"#181926\",\n \"--dsw-static-neutral-bluish-100\": \"#a5adcb\",\n \"--dsw-static-neutral-bluish-150\": \"#a5adcb\",\n \"--dsw-static-neutral-bluish-200\": \"#939ab7\",\n \"--dsw-static-neutral-bluish-300\": \"#8087a2\",\n \"--dsw-static-neutral-bluish-400\": \"#6e738d\",\n \"--dsw-static-neutral-bluish-500\": \"#5b6078\",\n \"--dsw-static-neutral-bluish-50\": \"#cad3f5\",\n \"--dsw-static-neutral-bluish-600\": \"#494d64\",\n \"--dsw-static-neutral-bluish-60\": \"#b8c0e0\",\n \"--dsw-static-neutral-bluish-700\": \"#363a4f\",\n \"--dsw-static-neutral-bluish-750\": \"#363a4f\",\n \"--dsw-static-neutral-bluish-75\": \"#b8c0e0\",\n \"--dsw-static-neutral-bluish-800\": \"#363a4f\",\n \"--dsw-static-neutral-bluish-850\": \"#24273a\",\n \"--dsw-static-neutral-bluish-875\": \"#1e2030\",\n \"--dsw-static-neutral-bluish-900\": \"#1e2030\",\n \"--dsw-static-neutral-bluish-950\": \"#181926\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #ed8796 20%, #24273a)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #ed8796 70%, #24273a)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #b16a7a 12%, transparent)\",\n \"--dsw-static-red-500\": \"#ed8796\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #ed8796 10%, #24273a)\",\n \"--dsw-static-red-600\": \"#ed8796\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #ed8796 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #ed8796 34%, #24273a)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-875)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.5)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.2)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(39, 39, 48, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-850)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted2\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l1\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2\": \"rgba(255, 255, 255, 0.12)\",\n \"--dsw-alias-border-l3\": \"rgba(255, 255, 255, 0.16)\",\n \"--dsw-alias-border-l4\": \"rgba(255, 255, 255, 0.2)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#8aadf4\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(255, 255, 255, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(255, 255, 255, 0.24)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(242, 90, 90, 0.15)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-450) 55%, var(--dsw-static-neutral-bluish-400))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-blue-300) 65%, var(--dsw-static-deepseek-400))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-00) 45%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-alias-label-primary-dimmed)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-800)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-700)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-550)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-800)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-900)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-900)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-active)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 45%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_MOCHA: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-mocha',\n colorScheme: 'dark',\n label: 'Mocha',\n accent: '#89b4fa',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #fab387 20%, #1e1e2e)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #fab387 70%, #1e1e2e)\",\n \"--dsw-static-amber-500\": \"#fab387\",\n \"--dsw-static-amber-600\": \"#fab387\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #fab387 18%, #11111b)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #89b4fa 24%, #1e1e2e)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #89b4fa 50%, #1e1e2e)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #89b4fa 66%, #1e1e2e)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-blue-500\": \"#89b4fa\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #89b4fa 10%, #1e1e2e)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #89b4fa 14%, #1e1e2e)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #89b4fa 18%, #1e1e2e)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #89b4fa 18%, #11111b)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #89b4fa 14%, #11111b)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #89b4fa 10%, #11111b)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #89b4fa 24%, #1e1e2e)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #89b4fa 36%, #1e1e2e)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #89b4fa 50%, #1e1e2e)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #89b4fa 66%, #1e1e2e)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-deepseek-500\": \"#89b4fa\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #89b4fa 10%, #1e1e2e)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #89b4fa 68%, #1e1e2e)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #89b4fa 18%, #11111b)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #89b4fa 14%, #11111b)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #a6e3a1 18%, #1e1e2e)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #a6e3a1 80%, #1e1e2e)\",\n \"--dsw-static-green-500\": \"#a6e3a1\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #a6e3a1 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #a6e3a1 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #a6e3a1 18%, #11111b)\",\n \"--dsw-static-neutral-00\": \"#cdd6f4\",\n \"--dsw-static-neutral-1000\": \"#11111b\",\n \"--dsw-static-neutral-100\": \"#a6adc8\",\n \"--dsw-static-neutral-150\": \"#a6adc8\",\n \"--dsw-static-neutral-200\": \"#9399b2\",\n \"--dsw-static-neutral-250\": \"#9399b2\",\n \"--dsw-static-neutral-300\": \"#7f849c\",\n \"--dsw-static-neutral-400\": \"#6c7086\",\n \"--dsw-static-neutral-500\": \"#585b70\",\n \"--dsw-static-neutral-50\": \"#cdd6f4\",\n \"--dsw-static-neutral-550\": \"#45475a\",\n \"--dsw-static-neutral-600\": \"#45475a\",\n \"--dsw-static-neutral-700\": \"#313244\",\n \"--dsw-static-neutral-800\": \"#313244\",\n \"--dsw-static-neutral-850\": \"#1e1e2e\",\n \"--dsw-static-neutral-900\": \"#181825\",\n \"--dsw-static-neutral-bluish-00\": \"#cdd6f4\",\n \"--dsw-static-neutral-bluish-1000\": \"#11111b\",\n \"--dsw-static-neutral-bluish-100\": \"#a6adc8\",\n \"--dsw-static-neutral-bluish-150\": \"#a6adc8\",\n \"--dsw-static-neutral-bluish-200\": \"#9399b2\",\n \"--dsw-static-neutral-bluish-300\": \"#7f849c\",\n \"--dsw-static-neutral-bluish-400\": \"#6c7086\",\n \"--dsw-static-neutral-bluish-500\": \"#585b70\",\n \"--dsw-static-neutral-bluish-50\": \"#cdd6f4\",\n \"--dsw-static-neutral-bluish-600\": \"#45475a\",\n \"--dsw-static-neutral-bluish-60\": \"#bac2de\",\n \"--dsw-static-neutral-bluish-700\": \"#313244\",\n \"--dsw-static-neutral-bluish-750\": \"#313244\",\n \"--dsw-static-neutral-bluish-75\": \"#bac2de\",\n \"--dsw-static-neutral-bluish-800\": \"#313244\",\n \"--dsw-static-neutral-bluish-850\": \"#1e1e2e\",\n \"--dsw-static-neutral-bluish-875\": \"#181825\",\n \"--dsw-static-neutral-bluish-900\": \"#181825\",\n \"--dsw-static-neutral-bluish-950\": \"#11111b\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #f38ba8 20%, #1e1e2e)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #f38ba8 70%, #1e1e2e)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #b36a83 12%, transparent)\",\n \"--dsw-static-red-500\": \"#f38ba8\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #f38ba8 10%, #1e1e2e)\",\n \"--dsw-static-red-600\": \"#f38ba8\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #f38ba8 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #f38ba8 34%, #1e1e2e)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-875)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.5)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.2)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(39, 39, 48, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-850)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted2\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l1\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2\": \"rgba(255, 255, 255, 0.12)\",\n \"--dsw-alias-border-l3\": \"rgba(255, 255, 255, 0.16)\",\n \"--dsw-alias-border-l4\": \"rgba(255, 255, 255, 0.2)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#89b4fa\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(255, 255, 255, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(255, 255, 255, 0.24)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(242, 90, 90, 0.15)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-450) 55%, var(--dsw-static-neutral-bluish-400))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-blue-300) 65%, var(--dsw-static-deepseek-400))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-00) 45%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-alias-label-primary-dimmed)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-800)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-700)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-550)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-800)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-900)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-900)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-active)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 45%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_FLAVORS: readonly CatppuccinFlavorInfo[] = [\n CATPPUCCIN_LATTE,\n CATPPUCCIN_FRAPPE,\n CATPPUCCIN_MACCHIATO,\n CATPPUCCIN_MOCHA,\n]\n","/**\n * Catppuccin syntax-highlighting token overrides for Shiki.\n *\n * DSH's default shiki.css (shipped by @deepseek-ai/dsh-client-ui-theme) defines\n * its own hard-coded syntax colours that are not Catppuccin. This module\n * supplies the canonical Catppuccin palette colours (sourced from the official\n * Shiki themes shipped by @shikijs/themes) for each of the four flavours, so\n * code blocks inside the DSH GUI match the Catppuccin project's syntax\n * highlighting.\n *\n * The foreground and background tokens are kept as var() references into the\n * plugin's own --dsw-* overrides (foreground -> label-primary, background ->\n * markdown-code-block), so they automatically track the active flavour. Every\n * other token is a literal hex from the Catppuccin palette.\n *\n * Styles (item M): the table is two-dimensional `SHIKI_TOKENS[flavor][style]`.\n * DSH's shiki.css only consumes the --shiki-* variables as colours (no style\n * attributes ride them — the highlighter owns font styles), so the\n * `italic-comments` variant is expressed as the comment colour hierarchy\n * difference it CAN carry: comments step down to the flavour's `subtext0`\n * (softer, clearly secondary) instead of `overlay2`. If a future DSH ships a\n * style-token layer, the variant should switch to font-style there instead.\n */\n\nimport type { CatppuccinFlavorId } from './palettes.ts'\nimport type { ShikiStyle } from '../state.ts'\n\n/** Shiki token names as defined by DSH's shiki.css. */\nexport type ShikiTokenName =\n | '--shiki-foreground'\n | '--shiki-background'\n | '--shiki-token-constant'\n | '--shiki-token-string'\n | '--shiki-token-comment'\n | '--shiki-token-keyword'\n | '--shiki-token-parameter'\n | '--shiki-token-function'\n | '--shiki-token-string-expression'\n | '--shiki-token-punctuation'\n | '--shiki-token-link'\n\n/** Per-flavour shiki token dictionary. */\nexport type ShikiTokens = Record<ShikiTokenName, string>\n\n/**\n * Canonical Catppuccin syntax colours per flavour.\n *\n * Colour → token mapping (from the official @shikijs/themes Catppuccin themes):\n * foreground → text\n * constant → peach\n * string → green\n * comment → overlay2\n * keyword → mauve\n * parameter → maroon\n * function → blue\n * string-expr → green (same as string)\n * punctuation → overlay2\n * link → blue (same as function)\n *\n * Background and foreground use var() references so they flow through the\n * flavour's --dsw-* overrides; the rest are literal hex.\n */\n\nconst BASE: Record<CatppuccinFlavorId, ShikiTokens> = {\n latte: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#fe640b', // peach\n '--shiki-token-string': '#40a02b', // green\n '--shiki-token-comment': '#7c7f93', // overlay2\n '--shiki-token-keyword': '#8839ef', // mauve\n '--shiki-token-parameter': '#e64553', // maroon\n '--shiki-token-function': '#1e66f5', // blue\n '--shiki-token-string-expression': '#40a02b', // green\n '--shiki-token-punctuation': '#7c7f93', // overlay2\n '--shiki-token-link': '#1e66f5', // blue\n },\n\n frappe: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#ef9f76', // peach\n '--shiki-token-string': '#a6d189', // green\n '--shiki-token-comment': '#949cbb', // overlay2\n '--shiki-token-keyword': '#ca9ee6', // mauve\n '--shiki-token-parameter': '#ea999c', // maroon\n '--shiki-token-function': '#8caaee', // blue\n '--shiki-token-string-expression': '#a6d189', // green\n '--shiki-token-punctuation': '#949cbb', // overlay2\n '--shiki-token-link': '#8caaee', // blue\n },\n\n macchiato: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#f5a97f', // peach\n '--shiki-token-string': '#a6da95', // green\n '--shiki-token-comment': '#939ab7', // overlay2\n '--shiki-token-keyword': '#c6a0f6', // mauve\n '--shiki-token-parameter': '#ee99a0', // maroon\n '--shiki-token-function': '#8aadf4', // blue\n '--shiki-token-string-expression': '#a6da95', // green\n '--shiki-token-punctuation': '#939ab7', // overlay2\n '--shiki-token-link': '#8aadf4', // blue\n },\n\n mocha: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#fab387', // peach\n '--shiki-token-string': '#a6e3a1', // green\n '--shiki-token-comment': '#9399b2', // overlay2\n '--shiki-token-keyword': '#cba6f7', // mauve\n '--shiki-token-parameter': '#eba0ac', // maroon\n '--shiki-token-function': '#89b4fa', // blue\n '--shiki-token-string-expression': '#a6e3a1', // green\n '--shiki-token-punctuation': '#9399b2', // overlay2\n '--shiki-token-link': '#89b4fa', // blue\n },\n}\n\n/** Official Catppuccin `subtext0` per flavour — the comment colour of the\n * `italic-comments` variant (a step softer than `overlay2`, so comments\n * read clearly as secondary). */\nconst SUBTEXT0: Record<CatppuccinFlavorId, string> = {\n latte: '#6c6f85',\n frappe: '#a5adce',\n macchiato: '#a5adcb',\n mocha: '#a6adc8',\n}\n\n/** Re-point the comment token of a base dictionary. */\nfunction withComment(tokens: ShikiTokens, comment: string): ShikiTokens {\n return { ...tokens, '--shiki-token-comment': comment }\n}\n\n/** Per-flavour × per-style shiki token dictionaries. */\nexport const SHIKI_TOKENS: Record<CatppuccinFlavorId, Record<ShikiStyle, ShikiTokens>> = {\n latte: {\n default: BASE.latte,\n 'italic-comments': withComment(BASE.latte, SUBTEXT0.latte),\n },\n frappe: {\n default: BASE.frappe,\n 'italic-comments': withComment(BASE.frappe, SUBTEXT0.frappe),\n },\n macchiato: {\n default: BASE.macchiato,\n 'italic-comments': withComment(BASE.macchiato, SUBTEXT0.macchiato),\n },\n mocha: {\n default: BASE.mocha,\n 'italic-comments': withComment(BASE.mocha, SUBTEXT0.mocha),\n },\n}","/**\n * Shared contract of the update-check feature — consumed by both halves:\n * the Host registers an exact webServer route answering this JSON payload,\n * and the Client settings row fetches that same-origin route and renders it.\n * This module is dependency-free so both bundles inline it.\n */\nimport { compareVersions, parseVersion } from './versions.ts'\nimport type { UpdateChannel } from './state.ts'\n// Type-only (erased at build time): `update-check.ts` stays dependency-free for\n// both bundles while the payload can still name the host kind.\nimport type { ShellKind } from './profile-detect.ts'\n\nexport type { UpdateChannel } from './state.ts'\nexport type { ShellKind } from './profile-detect.ts'\n\n/** The plugin's own npm name (the registry lookup key). */\nexport const PACKAGE_NAME = '@nonamelego/dsh-catppuccin'\n\n/**\n * npm registry abbreviated packument endpoint (the `install-v1` document).\n * The `latest` endpoint alone is not enough: this project ships prereleases\n * under the `beta` dist-tag while `latest` stays on the last stable, so the\n * check reads `dist-tags` to serve both channels.\n */\nexport const REGISTRY_PACKUMENT_URL =\n `https://registry.npmjs.org/${PACKAGE_NAME.replace('/', '%2F')}`\n\n/** Host route the Client row fetches (exact match, same origin). */\nexport const UPDATE_ROUTE_PATH = '/catppuccin/check-update'\n\n/** Network budget for the Host's registry lookup. */\nexport const UPDATE_FETCH_TIMEOUT_MS = 8000\n\n/** Budget for the CLIENT half's same-origin fetch of {@link UPDATE_ROUTE_PATH}\n * (R3, 2026-10-10 review). The Host's own registry lookup is capped at\n * {@link UPDATE_FETCH_TIMEOUT_MS}, so this only ever bites when the host\n * process itself stopped answering — without it a wedged host leaves the\n * settings row stuck in its `checking` phase, where the disabled check button\n * makes a retry impossible. Comfortably larger than the host budget so a\n * slow-but-alive registry lookup is never cut off client-side. */\nexport const UPDATE_CHECK_CLIENT_TIMEOUT_MS = 15_000\n\n/** The `dist-tags` object of an npm packument. */\nexport interface DistTags {\n latest?: string\n beta?: string\n}\n\n/** The newest release a given install should chase, and on which channel. */\nexport interface NewestRelease {\n version: string\n channel: UpdateChannel\n}\n\n/**\n * The copyable CLI upgrade command for one channel (`dsh plugin` is a thin\n * pnpm forwarder). The profile name comes from the Host's runtime probe\n * (`src/profile-detect.ts`), never hard-coded, so the command works on any\n * deployment out of the box.\n *\n * ⚠️ **只适用于 `web` 与 `community-desktop`**(社区壳的应用内 DSH 终端里有效)。\n * 官方 Electron 壳的用户没有可达的终端入口(`resources/runtime/cli/bin/dsh.cmd`\n * 在代码上允许 `manageDesktopProfile: true`,但官方壳 UI 不提供终端),那条路改用\n * {@link pluginSpecFor} + 应用内「插件」页重装。\n * @param channel - the dist-tag to chase.\n * @param profile - the DSH profile name to target.\n */\nexport function updateCommandFor(channel: UpdateChannel, profile: string): string {\n return `dsh plugin --profile ${profile} add ${PACKAGE_NAME}@${channel}`\n}\n\n/**\n * The value to paste into a plugin manager's \"add plugin\" field — the shape the\n * official Electron shell's Plugins page accepts. Its 升级 path is\n * 「先删除、再重新安装同一个包名」, so the spec (not a CLI command) is the\n * copyable artefact there.\n * @param channel - the dist-tag to chase.\n */\nexport function pluginSpecFor(channel: UpdateChannel): string {\n return `${PACKAGE_NAME}@${channel}`\n}\n\n/**\n * Pick the newest release worth reporting for the given install:\n * - with NO channel preference: a stable install chases only `latest` (never\n * downgrades onto a beta), while a prerelease install (e.g. a\n * `beta`-tagged version) also chases `beta` — so beta users see newer\n * betas, and a stable release that outranks their prerelease promotes\n * them via `@latest`;\n * - an explicit `beta` preference (the settings row's prerelease pick)\n * chases `beta` even from a stable install — beta testers opt in without\n * changing their install; the newest of the two tags still wins, so a\n * newer stable promotes them back onto `@latest`;\n * - an explicit `latest` preference pins the check to the stable tag —\n * never a beta, even from a prerelease install.\n * @param current - the installed version.\n * @param tags - the registry's dist-tags.\n * @param preferredChannel - optional persisted channel preference (item I).\n * @returns the newest candidate and its channel, or null when nothing applies.\n */\nexport function selectNewest(current: string, tags: DistTags, preferredChannel?: UpdateChannel): NewestRelease | null {\n const candidates: NewestRelease[] = []\n if (tags.latest !== undefined) candidates.push({ version: tags.latest, channel: 'latest' })\n if (preferredChannel === 'beta') {\n // Beta chase, opt-in: follow the beta tag even from a stable install.\n if (tags.beta !== undefined) candidates.push({ version: tags.beta, channel: 'beta' })\n } else if (preferredChannel === undefined) {\n // No preference: prerelease installs chase beta on top of latest.\n const parsed = parseVersion(current)\n if (tags.beta !== undefined && parsed !== null && parsed.prerelease.length > 0) {\n candidates.push({ version: tags.beta, channel: 'beta' })\n }\n }\n // preferredChannel === 'latest': candidates hold the stable tag only.\n if (candidates.length === 0) return null\n let best = candidates[0]\n for (const candidate of candidates.slice(1)) {\n if (compareVersions(best.version, candidate.version) < 0) best = candidate\n }\n return best\n}\n\n/** Stable machine-readable outcome code (borrowed from the plugin-update\n * error-code discipline of dsh-vision-toolkit): the Client maps it to copy\n * instead of sniffing human text. `network.*` splits the old catch-all\n * `network` (item U): `network.local` means the browser→Host hop failed\n * (host unreachable / DNS — \"check your network\"), `network.upstream` means\n * the Host reached the registry but the lookup timed out (\"npm is\n * temporarily unavailable\"). */\nexport type UpdateErrorCode =\n | 'ok'\n | 'network.local' // the same-origin fetch itself failed (client side)\n | 'network.upstream' // the Host's registry fetch timed out\n | 'registry-unreachable' // npm registry could not be reached (fetch threw)\n | 'registry-http' // registry answered with a non-2xx status\n | 'no-dist-tags' // registry returned no usable dist-tags\n | 'invalid-response' // registry response could not be parsed\n\n/** How this package is installed inside the probed DSH profile. */\nexport type InstallSource = 'registry' | 'link' | 'file' | 'git' | 'unknown'\n\n/** Runtime that answered the check — drives the copy (command hint / restart). */\nexport type UpdateEnv = 'desktop' | 'web'\n\n/**\n * JSON payload of the update check. `ok: false` carries a human-readable\n * `error` plus a stable `code`; `ok: true` carries the comparison result.\n * The Host owns the semver comparison, the channel selection, and the\n * profile probe (single source of truth), so the Client never parses\n * versions or guesses the profile name itself.\n */\nexport interface UpdateCheckPayload {\n /** Whether the registry lookup succeeded. */\n ok: boolean\n /** Installed version (from this package's own manifest). */\n current?: string\n /** Newest release worth chasing (`latest`, plus `beta` for prerelease installs). */\n latest?: string\n /** `latest` is strictly newer than `current`. */\n outdated?: boolean\n /** The dist-tag the newest release came from. */\n channel?: UpdateChannel\n /** Copyable CLI upgrade command (present when outdated). Only on `web` and\n * `community-desktop` — the official shell has no reachable CLI path. */\n updateCommand?: string\n /** `pkg@tag` spec for the Plugins page's \"add plugin\" field. Present instead\n * of {@link updateCommand} on the official desktop shell. */\n updateSpec?: string\n /** Which host answered the check (drives the copy). */\n shell?: ShellKind\n /** DSH profile name the upgrade command targets (probed, not guessed). */\n profile?: string\n /** Whether the profile probe actually found the install (false = fallback). */\n profileDetected?: boolean\n /** Runtime that answered: DSH Desktop vs standard dsh web (drives copy). */\n env?: UpdateEnv\n /** How the package is installed in that profile (drives copy). */\n installSource?: InstallSource\n /** ISO timestamp of the check (registry lookup moment). */\n checkedAt?: string\n /** Stable outcome code (see {@link UpdateErrorCode}). */\n code?: UpdateErrorCode\n /** Failure detail (only when `ok` is false). */\n error?: string\n}\n","/**\n * Fault-tolerant registration for the plugin's boot-critical wiring.\n *\n * Client and Host share one failure shape: an entry whose `apply()` throws is\n * marked `failed`, the assembly aborts the whole boot (`web boot: N entries\n * did not activate`), and the official desktop's crash rescue then runs\n * `disableAllPlugins()` — taking EVERY third-party plugin down with it. A peer\n * plugin already owning what we are about to register is the realistic\n * trigger (language packs and their BCP 47 ids — issue #23; a duplicate\n * install and its route / slot / theme ids), and the right answer to\n * \"someone else already did this\" is to skip OUR copy — never to fail the\n * boot. Full evidence chain and the per-call-site audit live in\n * `docs/issue-23-registration-tolerance.md`.\n *\n * Known \"already owned\" shapes are skipped quietly — the peer's registration\n * stands, matching `dsh-locale-pack`'s own tolerance. Anything else is logged\n * and skipped too: no registration in this plugin is worth the user's whole\n * plugin set. (To restore fail-fast for a class of errors, `throw error` in\n * the warn branch — every call site routes through here on purpose.)\n */\n\n/** The \"another party already owns this\" messages the runtimes throw, checked\n * against the 0.2.0-rc.2 sources (table in the doc's §6):\n * - `locale \"ja\" is already registered` (dsh-client-locale addLanguage)\n * - `locale namespace \"…\" already has locale \"…\"` (dsh-client-locale register)\n * - `theme \"…\" is already registered` (dsh-client-ui-theme register)\n * - `list slot \"…\" already has an entry with id \"…\"` (dsh-client-ui-slots)\n * - `webserver: duplicate exact route \"…\"` (dsh-host-webserver register) */\nconst ALREADY_OWNED = /already (?:registered|has locale|has an entry)|duplicate .*route/u\n\n/**\n * Run one registration call, degrading any failure to a no-op disposer.\n * @param run - the registration call, returning its disposer (if any).\n * @returns the real disposer, or a no-op when the registration was skipped.\n */\nexport function tolerantRegistration(run: () => (() => void) | void): () => void {\n try {\n return run() ?? (() => {})\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (!ALREADY_OWNED.test(message)) {\n console.warn(`[dsh-catppuccin] registration skipped — ${message}`)\n }\n return () => {}\n }\n}\n","/**\n * Browser half of the durable Catppuccin state — an adapter over BOTH shapes\n * of the OFFICIAL settings seam, replacing the pre-0.5.0 `/catppuccin/state`\n * route wrapper.\n *\n * The seam changed shape in DSH 0.1.7-alpha.1 (issue #15) and both shapes are\n * in the wild (`latest` = 0.1.5-rc.3 on the old one, `next` = 0.1.7-rc.1 on\n * the new one), so this module binds whichever the host serves:\n *\n * - `ctx.configForms` (>= 0.1.7-alpha.1): the plugin's volatile `Config`\n * projected into a form keyed by the PROFILE ENTRY id, addressed through\n * `configForms.get(CATPPUCCIN_ENTRY_ID)`.\n * - `ctx.settingsScope` (<= 0.1.6-alpha.2): a namespace the Host half\n * registered, bound with `settingsScope.bind({ namespace })`.\n *\n * The two are not alike at the type level, but their SNAPSHOTS are\n * field-for-field identical (`status / value / base / user / revision /\n * writable / mode`), so one {@link DurableScope} interface covers both. Their\n * three behavioural differences are confined INSIDE the channel objects and\n * are deliberately not reachable by callers:\n *\n * 1. \"no user layer yet\" — the new form's `user` is the profile patch's\n * `override`, which defaults to `{}` (so `!== undefined` never fires\n * there); the legacy document omits the field entirely when it holds no\n * such section. → {@link DurableScope.hasUserLayer}.\n * 2. the write fence — the new controller takes an OPTIONAL\n * `expectedRevision` and reports a refusal as `false`; the legacy one has\n * no fence parameter at all and reports refusal as a SILENT resolve. Both\n * therefore resolve the fence themselves (`pendingRevision ??\n * snapshot.revision` on the new one) unless a caller supplies one, and\n * {@link persistStateToScope} deliberately supplies NONE — see the note\n * there. The only fence this module could offer is the revision a debounced\n * burst STARTED from, and a write of our own that lands inside the burst\n * moves the document past it; forwarding that older base makes the Host\n * refuse a write that must succeed, which the caller then reads as \"another\n * window changed the document\" and answers by reverting the user's newest\n * change (the fast-switching half of the 2026-10-01 report). Deciding the\n * fence stays the channel's job, exactly as before — the configForms\n * channel still forwards one when a staged editor supplies it.\n * → {@link DurableScope.write}.\n * 3. the refusal signal — only the new channel can report `refused`; the\n * legacy one cannot, which is why the read-side revision guard in\n * {@link persistStateToScope} must stay in place for BOTH channels.\n *\n * Every failure is still non-fatal: the plugin keeps working from browser\n * localStorage alone (the in-browser cache), losing only cross-restart\n * durability on profiles where the settings transport is absent or\n * process-local.\n */\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\n// Type-only: pulls the configForms Context merge and the form contract.\nimport type { ConfigForm, ConfigFormSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n CATPPUCCIN_ENTRY_ID,\n CATPPUCCIN_SETTINGS_NS,\n hasUserLayerSection,\n settingsSectionFromState,\n settingsSectionsEqual,\n stateFromSettingsSection,\n type CatppuccinSettingsSection,\n type CatppuccinState,\n} from '../state.ts'\n\n/** Client-side sync state of one settings namespace — the SHARED shape of\n * both seams (`ConfigFormSnapshot` on 0.1.7+, the scope snapshot before it;\n * the fields agree one for one, which is what makes the adapter possible). */\nexport interface DurableSnapshot<T> {\n /** `loading` until the first accepted section, `ready` while one stands,\n * `unavailable` when the namespace is not exposed to this client or the\n * connection keeps preferences process-local (memory mode). */\n status: 'loading' | 'ready' | 'unavailable'\n /** Last accepted schema-resolved section. */\n value: T | undefined\n /** Composition layer the Host resolved {@link value} over. */\n base: unknown\n /** Raw user layer as stored, when one exists. */\n user: unknown\n /** Revision fencing the next write. */\n revision: number | undefined\n /** Whether the Host document accepts writes; memory mode never does. */\n writable: boolean\n /** `host` syncs with the Host document; `memory` keeps a remote browser\n * process-local. */\n mode: 'host' | 'memory'\n}\n\n/** How one write ended. `refused` is only observable on the new channel. */\nexport type WriteOutcome = 'accepted' | 'refused' | 'failed'\n\n/** One settings channel: everything the two seams disagree about lives here. */\nexport interface DurableScope<T> {\n /** Which seam answered — diagnostics and test assertions only. */\n readonly kind: 'configForms' | 'settingsScope' | 'none'\n getSnapshot(): DurableSnapshot<T>\n subscribe(listener: () => void): () => void\n /** Whether the durable store already holds a user layer. The predicate is\n * per-channel on purpose (see difference 1 in the module header). */\n hasUserLayer(snapshot: DurableSnapshot<T>): boolean\n /** Issue one atomic write. Whether {@link baseRevision} becomes the Host's\n * fence is the channel's decision, never the caller's (difference 2).\n * `baseRevision` is for STAGED editors — upstream's contract is \"the revision\n * read before editing\", so a conflict preserves the draft. The debounced\n * whole-state write-back in {@link persistStateToScope} passes none on\n * purpose: its base is the pre-burst revision, not an edit-start revision. */\n write(ops: readonly SettingsPathOpView[], baseRevision?: number | undefined): Promise<WriteOutcome>\n}\n\n/** The snapshot an unbound scope reports: the pre-0.5.0 \"transport absent\"\n * degradation, where localStorage is the only store. */\nconst UNBOUND_SNAPSHOT: DurableSnapshot<never> = {\n status: 'unavailable',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'memory',\n}\n\n/** Whether the scope is usable for durable persistence: the document is\n * resolved (`ready`) and the Host persistence is active (`host`). A `memory`\n * scope (non-loopback pages / absent transport) or a not-yet-ready one is\n * NOT usable — the caller keeps localStorage as the only store. */\nexport function isScopeUsable(snapshot: DurableSnapshot<unknown>): boolean {\n return snapshot.status === 'ready' && snapshot.mode === 'host'\n}\n\n/** The local state contract (with the synthetic `version`) for a usable\n * scope snapshot; `null` while the section is not resolved. */\nexport function durableStateFromSnapshot(\n snapshot: DurableSnapshot<CatppuccinSettingsSection>,\n): CatppuccinState | null {\n if (!isScopeUsable(snapshot) || snapshot.value === undefined) return null\n return stateFromSettingsSection(snapshot.value)\n}\n\n/** The NEW seam's channel (DSH >= 0.1.7-alpha.1). */\nfunction configFormsScope(\n form: ConfigForm<CatppuccinSettingsSection>,\n): DurableScope<CatppuccinSettingsSection> {\n return {\n kind: 'configForms',\n getSnapshot: () => form.getSnapshot() as ConfigFormSnapshot<CatppuccinSettingsSection>,\n subscribe: (listener) => form.subscribe(listener),\n // The form's `user` is the profile patch's `override`, which the Host\n // defaults to `{}` — so an EMPTY OBJECT is what \"no user layer yet\" looks\n // like here, and it must not be mistaken for a real user layer.\n hasUserLayer: (snapshot) => hasUserLayerSection(snapshot.user),\n write: async (ops, baseRevision) => {\n try {\n // The returned boolean is the only refusal signal any seam gives us;\n // a transport failure rejects instead. `baseRevision` is forwarded\n // only when a caller supplies one (staged editors) — the debounced\n // write-back passes none and lets the controller fence with its own\n // `pendingRevision ?? snapshot.revision`, which is strictly fresher.\n return await form.mutate(ops, baseRevision) ? 'accepted' : 'refused'\n } catch {\n return 'failed'\n }\n },\n }\n}\n\n/**\n * The LEGACY seam's surface (DSH <= 0.1.6-alpha.2). Declared structurally\n * because 0.1.7 removed it from the published types while this plugin still\n * has to run on hosts that only have it, and reaching for `any` would hide a\n * real shape change.\n */\ninterface LegacyScope<T> {\n getSnapshot(): DurableSnapshot<T>\n subscribe(listener: () => void): () => void\n /** Note the absent `expectedRevision`: the legacy controller resolves the\n * fence itself (`pendingRevision ?? snapshot.revision`). */\n mutate(ops: readonly SettingsPathOpView[]): Promise<void>\n}\ninterface LegacyScopeBinder {\n bind<T>(spec: { namespace: string }): LegacyScope<T>\n}\n\n/** The LEGACY seam's channel (DSH <= 0.1.6-alpha.2). */\nfunction legacyScope(scope: LegacyScope<CatppuccinSettingsSection>): DurableScope<CatppuccinSettingsSection> {\n return {\n kind: 'settingsScope',\n getSnapshot: () => scope.getSnapshot(),\n subscribe: (listener) => scope.subscribe(listener),\n // The legacy document maps over the namespaces it has a section for, so\n // \"no user layer\" is an ABSENT field — the predicate 0.5.x shipped.\n hasUserLayer: (snapshot) => snapshot.user !== undefined,\n write: async (ops) => {\n try {\n // NO baseRevision on purpose: the legacy controller resolves the fence\n // itself and therefore retries with the newer revision. Forwarding our\n // older base would make a write that succeeds today fail — and that\n // failure is unobservable (the controller resolves it silently), so we\n // would not even notice.\n await scope.mutate(ops)\n return 'accepted'\n } catch {\n return 'failed'\n }\n },\n }\n}\n\n/**\n * Bind whichever settings channel this host serves, late and without blocking.\n *\n * Both bindings ride OPTIONAL injections: a service the deployment never\n * provides simply never fires its callback (it does not hold the plugin\n * back), and the two names cannot both be live in one host — 0.1.7-alpha.1\n * removed `settingsScope` from the service set, and 0.1.6 and earlier know\n * nothing of `configForms`. Until one binds, the scope reports the unbound\n * snapshot and every write short-circuits, which is exactly the\n * \"settings transport unavailable\" degradation the rows already handle.\n * @param ctx - client root context.\n * @returns the scope facade, bound for the lifetime of the caller's fiber.\n */\nexport function createDurableScope(ctx: Context): DurableScope<CatppuccinSettingsSection> {\n let current: DurableScope<CatppuccinSettingsSection> | undefined\n let offBound: (() => void) | undefined\n const listeners = new Set<() => void>()\n const notify = (): void => {\n for (const listener of [...listeners]) listener()\n }\n const attach = (next: DurableScope<CatppuccinSettingsSection> | undefined): void => {\n if (next === current) return\n offBound?.()\n current = next\n offBound = next?.subscribe(notify)\n // Re-run hydration/adoption: the durable state may only become readable\n // once a late-arriving service publishes its first snapshot.\n notify()\n }\n\n ctx.inject(['configForms'], (formsCtx) => {\n attach(configFormsScope(formsCtx.configForms.get<CatppuccinSettingsSection>(CATPPUCCIN_ENTRY_ID)))\n return () => { attach(undefined) }\n })\n ctx.inject(['settingsScope'], (legacyCtx) => {\n // `settingsScope` is not part of the 0.1.7 Context merge (the service is\n // gone there), so the legacy lookup is narrowed explicitly.\n const binder = (legacyCtx as unknown as { settingsScope?: LegacyScopeBinder }).settingsScope\n if (binder !== undefined) {\n attach(legacyScope(binder.bind<CatppuccinSettingsSection>({ namespace: CATPPUCCIN_SETTINGS_NS })))\n }\n return () => { attach(undefined) }\n })\n\n return {\n get kind() { return current?.kind ?? 'none' },\n getSnapshot: () => current?.getSnapshot()\n ?? UNBOUND_SNAPSHOT as DurableSnapshot<CatppuccinSettingsSection>,\n subscribe: (listener) => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n // Never reached while unbound: the caller bails out in\n // `durableStateFromSnapshot` before asking.\n hasUserLayer: (snapshot) => current?.hasUserLayer(snapshot) ?? false,\n write: async (ops, baseRevision) => current?.write(ops, baseRevision) ?? 'failed',\n }\n}\n\n/** One atomic mutation covering the whole local state (revision-fenced).\n * Writing every field keeps the section self-contained — a partial write\n * could otherwise leave a knob stuck on a stale override after a document\n * edit elsewhere. */\nfunction stateToMutateOps(state: CatppuccinState): SettingsPathOpView[] {\n const section = settingsSectionFromState(state)\n return [\n { op: 'set', path: ['flavor'], value: section.flavor },\n { op: 'set', path: ['glass', 'enabled'], value: section.glass.enabled },\n { op: 'set', path: ['glass', 'mode'], value: section.glass.mode },\n { op: 'set', path: ['glass', 'blur'], value: section.glass.blur },\n { op: 'set', path: ['glass', 'frost'], value: section.glass.frost },\n { op: 'set', path: ['glass', 'brightness'], value: section.glass.brightness },\n { op: 'set', path: ['autoCheck'], value: section.autoCheck },\n { op: 'set', path: ['updateChannel'], value: section.updateChannel },\n { op: 'set', path: ['overrides'], value: section.overrides },\n { op: 'set', path: ['shikiStyle'], value: section.shikiStyle },\n ]\n}\n\n/** Outcome of one durable persist attempt (item C/X). */\nexport type PersistOutcome =\n /** The mutation was issued (the Host may still fence-stall it later). */\n | 'written'\n /** The local state already equals the document — nothing to write. */\n | 'noop'\n /** The document moved past the revision the local state was derived from:\n * the local change is a stale write-back and was NOT written — the\n * remote (newer) state wins and the caller should adopt it + notify. */\n | 'stale'\n /** The write failed (transport error / rejected mutation). */\n | 'error'\n\n/**\n * Read-side consistency guard for the durable persist (items C/X).\n *\n * The WRITE side belongs to the channel — no optimistic locking is re-built\n * here — but the persist path deliberately does NOT hand it a fence: the base\n * below is the revision the local state was derived from (captured at SCHEDULE\n * time), which is the right input for the READ-side guard and the wrong input\n * for a write fence. A write of ours that lands inside the debounce window (or\n * is still in flight when the flush runs) moves the document past that base\n * while our mirror has not caught up, so fencing the next write with it makes\n * the Host refuse a write that must succeed; the refusal is then reported as\n * `stale`, and the caller adopts the remote state — silently reverting the\n * user's newest change. That is the 2026-10-01 \"switching the mica/compat mode\n * quickly sometimes fails\" report: two mode switches ~300ms apart, the second\n * one reverted.\n *\n * What a fence cannot see is a STALE LOCAL VIEW: tab A reads an old\n * localStorage value, the user changes flavour, and the debounced flush writes\n * that old-based state over tab B's already-committed newer choice. That is\n * what the guard below is for, and it is also the ONLY conflict detector the\n * legacy seam can offer — that seam resolves a refused write silently, so\n * without it a concurrent edit would be lost without a trace.\n *\n * The guard compares the revision the local state was derived from\n * (`baseRevision`, captured at schedule time) with the snapshot revision at\n * flush time:\n * - equal → the document did not move while we were debouncing → write.\n * - moved, and the remote section equals our own last written section →\n * the movement is our own write's echo, safe to write the newer change.\n * - moved otherwise → an external edit landed mid-debounce; the local\n * change is stale, so it is abandoned and `stale` is returned so the\n * caller can adopt the remote state and surface the conflict.\n * Also returns `noop` when the local state already equals the document\n * (the normal echo back of our own committed writes; previously this wrote\n * a redundant identical mutation).\n */\nexport async function persistStateToScope(\n scope: DurableScope<CatppuccinSettingsSection>,\n state: CatppuccinState,\n options: {\n /** Snapshot revision the local state was derived from (captured at\n * schedule time). Omit to skip the read-side guard entirely. */\n baseRevision?: number | undefined\n /** Section of the last successfully issued write (our own echo\n * fingerprint — revision movement matching it is not a conflict). */\n lastWrittenSection?: CatppuccinSettingsSection | undefined\n } = {},\n): Promise<PersistOutcome> {\n const snapshot = scope.getSnapshot()\n if (!isScopeUsable(snapshot)) return 'error'\n const remote = durableStateFromSnapshot(snapshot)\n const localSection = settingsSectionFromState(state)\n if (remote !== null && settingsSectionsEqual(settingsSectionFromState(remote), localSection)) {\n return 'noop'\n }\n const { baseRevision, lastWrittenSection } = options\n if (baseRevision !== undefined && snapshot.revision !== undefined && snapshot.revision !== baseRevision) {\n const ourOwnEcho = lastWrittenSection !== undefined\n && remote !== null\n && settingsSectionsEqual(settingsSectionFromState(remote), lastWrittenSection)\n if (!ourOwnEcho) return 'stale'\n }\n // No fence: the channel resolves `pendingRevision ?? snapshot.revision` when\n // the write actually goes out, which is both fresher than our captured base\n // and aware of our own superseded/in-flight writes (difference 2 in the\n // module header). The Host still validates it against the document, so an\n // external edit the mirror has not seen yet is still refused.\n const outcome = await scope.write(stateToMutateOps(state))\n if (outcome === 'accepted') return 'written'\n // A refusal means the Host's document moved past what this state was derived\n // from — the same condition the read-side guard above reports. The channel\n // has already re-read the Host state, so the caller can adopt it and tell\n // the row about the conflict.\n if (outcome === 'refused') return 'stale'\n return 'error'\n}\n\nlet pendingTimer: number | undefined\nlet pendingWrite: (() => void) | undefined\n\n/**\n * Debounced trailing persist: after a burst of changes (a slider drag emits a\n * stream of snapshot updates) the write happens once, a short beat after the\n * last change. Pass an accessor so the state snapshot is taken at flush time,\n * never stale.\n */\nexport function scheduleDurablePersist(write: () => void, delayMs = 300): void {\n if (pendingTimer !== undefined) window.clearTimeout(pendingTimer)\n pendingWrite = write\n pendingTimer = window.setTimeout(() => {\n pendingTimer = undefined\n const run = pendingWrite\n pendingWrite = undefined\n if (run !== undefined) void Promise.resolve().then(run).catch(() => { /* best-effort */ })\n }, delayMs)\n}\n\n/** Drop any queued persist (plugin unload / page teardown). */\nexport function cancelDurablePersist(): void {\n if (pendingTimer !== undefined) window.clearTimeout(pendingTimer)\n pendingTimer = undefined\n pendingWrite = undefined\n}\n\n/**\n * Capture-once holder for the revision a debounced write is based on (audit\n * F2, 2026-09-22).\n *\n * The read-side guard in {@link persistStateToScope} only means anything if\n * `baseRevision` is the revision the LOCAL state was derived from — i.e.\n * sampled when the change was SCHEDULED. Reading it inside the flush instead\n * made the comparison a tautology: the flush and the guard's own\n * `scope.getSnapshot()` run in the same synchronous block, so the two\n * revisions are always equal and `'stale'` is unreachable. The effect was a\n * silently lost read-side protection: with two windows open, an external edit\n * landing inside the 300 ms debounce window was overwritten by the stale local\n * state and the conflict banner never appeared.\n *\n * `capture` keeps the FIRST revision of a burst (`??=`, not assignment): a\n * slider drag emits several changes, and the local state each of them is based\n * on is still the one that was current when the burst started. `take` clears\n * the slot as it reads, so the next burst starts fresh — including when the\n * flush bails out (unusable scope), where the value must not leak forward.\n */\nexport function createBaseRevisionTracker(): {\n /** Sample the base revision once per burst (later calls in the same burst are no-ops). */\n capture: (read: () => number | undefined) => void\n /** Consume the captured revision (undefined when the burst never captured one). */\n take: () => number | undefined\n} {\n let pending: number | undefined\n return {\n capture(read) {\n if (pending === undefined) pending = read()\n },\n take() {\n const value = pending\n pending = undefined\n return value\n },\n }\n}\n","/**\n * Catppuccin themes for the DeepSeek Harness web GUI — browser half.\n *\n * Registers the four Catppuccin flavours (Latte light / Frappé, Macchiato,\n * Mocha dark) into the official ThemeRuntime, so they become selectable\n * themes whose --dsw-* token overrides fully remap the UI palette. The\n * official Appearance row persists only the built-in light/dark/system\n * preferences, so this plugin also owns a settings row (\"Catppuccin\") that\n * lists the four flavours; selecting one switches the theme and persists the\n * flavour.\n *\n * Persistence is two-tier since 0.5.0. The choice lives in two stores:\n * - localStorage keys (`dsh.catppuccin.*`) — the in-browser cache: instant\n * restore at boot, the cross-tab `storage` event bus, and the fallback\n * when the settings transport is unavailable;\n * - the official settings seam (registered/declared by the Host half in\n * `src/index.ts`) — the source of truth, bound here through\n * `createDurableScope`, which adapts whichever seam the host serves\n * (`ctx.settingsScope` up to 0.1.6-alpha.2, `ctx.configForms` from\n * 0.1.7-alpha.1 — see `src/client/state-sync.ts`). It exists because\n * localStorage is per-browser and per-origin while the DSH home is the\n * machine-wide truth (full rationale in `src/state.ts`). The pre-0.5.0\n * Host file + `/catppuccin/state` route are gone — the Host migrates the\n * old file into the store once.\n * At boot the plugin fast-applies localStorage, then hydrates from the scope\n * snapshot once it resolves and mirrors it back into localStorage; if the\n * document holds nothing while this browser session already chose something,\n * that choice is pushed to the document. Every user change is written to\n * localStorage immediately and pushed to the scope (debounced) so it\n * survives the next Desktop restart. Without a usable scope (memory mode /\n * absent transport) everything degrades to localStorage alone. The debounced\n * write is read-side guarded (item C/X): a flush whose base revision the\n * document has moved past abandons the stale write, re-adopts the remote\n * state, and tells the update row \"另一窗口已更新,本地改动未保存\".\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ThemeRuntime, ThemeTokens } from '@deepseek-ai/dsh-client-ui-theme/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the renderer's Context merge (ctx.slots) — since DSH\n// 0.1.2 the slots registry lives in dsh-client-ui-renderer (the old\n// dsh-client-runtime package is gone).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\n// Type-only: pulls the settings-surface SlotMap merge (settings.general.item)\n// and, on 0.1.7+, the configForms Context merge the durable scope binds.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { CatppuccinRow, type CatppuccinRowInjected } from './CatppuccinRow.tsx'\nimport { CatppuccinDetailCard, type CatppuccinDetailCardInjected } from './detail-card.tsx'\nimport { de, en, es, fr, ja, ko, zh, type CatppuccinKey } from './locales.ts'\nimport { LinksRow } from './LinksRow.tsx'\nimport { CATPPUCCIN_FLAVORS, type CatppuccinFlavorId, type CatppuccinFlavorInfo } from './palettes.ts'\nimport { SHIKI_TOKENS } from './shiki-tokens.ts'\nimport { GlassLayer } from './glass/glass-layer.ts'\nimport { GlassRow, type GlassRowInjected } from './glass/glass-row.tsx'\nimport { UpdateRow, type UpdateRowInjected } from './UpdateRow.tsx'\nimport type { UpdateCheckPayload } from '../update-check.ts'\nimport { PACKAGE_NAME, UPDATE_CHECK_CLIENT_TIMEOUT_MS, UPDATE_ROUTE_PATH } from '../update-check.ts'\nimport { tolerantRegistration } from '../registration-tolerance.ts'\nimport {\n CATPPUCCIN_ENTRY_ID,\n DEFAULT_AUTO_CHECK,\n DEFAULT_SHIKI_STYLE,\n DEFAULT_UPDATE_CHANNEL,\n hasUnpersistableOverrides,\n isDefaultState,\n sanitizeOverrides,\n settingsSectionFromState,\n settingsSectionsEqual,\n STATE_VERSION,\n type CatppuccinSettingsSection,\n type CatppuccinState,\n type FlavorValue,\n type ShikiStyle,\n type UpdateChannel,\n} from '../state.ts'\nimport {\n createDurableScope,\n cancelDurablePersist,\n createBaseRevisionTracker,\n durableStateFromSnapshot,\n isScopeUsable,\n persistStateToScope,\n scheduleDurablePersist,\n} from './state-sync.ts'\n// The glass stylesheet is intentionally NOT imported here: it ships as the\n// generated `GLASS_CSS_TEXT` string (`glass-css.gen.ts`, built by\n// scripts/gen-glass-css.mjs) and `GlassLayer` mounts/removes the <style>\n// tag on enable/disable — item II (lazy glass CSS).\n\n/** Locale namespace owned by this plugin. */\nexport const NS = 'catppuccin'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The Catppuccin settings row's copy. */\n catppuccin: CatppuccinKey\n }\n}\n\n/** localStorage key carrying the persisted flavour choice. */\nexport const FLAVOR_STORAGE_KEY = 'dsh.catppuccin.flavor'\n\n/** localStorage key recording the last built-in theme preference. */\nexport const RESTORE_STORAGE_KEY = 'dsh.catppuccin.restore'\n\n/** localStorage key carrying the auto-check update preference (item H). */\nexport const AUTO_CHECK_KEY = 'dsh.catppuccin.autoCheck'\n\n/** localStorage key carrying the update channel preference (item I). */\nexport const UPDATE_CHANNEL_KEY = 'dsh.catppuccin.updateChannel'\n\n/** localStorage key carrying the user token overrides JSON (item K). */\nexport const OVERRIDES_KEY = 'dsh.catppuccin.overrides'\n\n/** localStorage key carrying the shiki style preference (item M). */\nexport const SHIKI_STYLE_KEY = 'dsh.catppuccin.shikiStyle'\n\n/** Accepted flavour values — the four registered theme ids plus `off`. These\n * MUST stay in sync with the registered themes (guarded by\n * tests/palettes.spec.ts) because the persisted value is the theme id. */\nexport const CATPPUCCIN_FLAVOR_VALUES = [\n ...CATPPUCCIN_FLAVORS.map((f) => f.themeId),\n 'off',\n] as const\n\n/** `off` means: fall back to the official theme (default). */\nexport type FlavorChoice = (typeof CATPPUCCIN_FLAVOR_VALUES)[number]\n\n/** The flavour whose themeId this is, or `off`. */\nexport function flavorFromThemeId(themeId: string): FlavorChoice {\n return CATPPUCCIN_FLAVORS.some((f) => f.themeId === themeId) ? themeId as FlavorChoice : 'off'\n}\n\n/** The flavour registered for a theme id, or undefined when not a Catppuccin theme. */\nexport function flavorInfo(themeId: string): CatppuccinFlavorInfo | undefined {\n return CATPPUCCIN_FLAVORS.find((f) => f.themeId === themeId)\n}\n\n/** Read the persisted flavour (absent / unknown values mean the default `off`). */\nexport function readFlavor(): FlavorChoice {\n try {\n const raw = localStorage.getItem(FLAVOR_STORAGE_KEY)\n return raw !== null && (CATPPUCCIN_FLAVOR_VALUES as readonly string[]).includes(raw)\n ? raw as FlavorChoice\n : 'off'\n } catch {\n return 'off'\n }\n}\n\n/** Whether localStorage carries an EXPLICIT `off` flavour choice.\n *\n * `readFlavor()` maps both \"no value\" and \"off\" to `off`, and the two are not\n * the same thing: an absent value only means THIS browser/origin never chose\n * (a first visit, cleared site data, or a second Desktop instance that landed\n * on the next free loopback port), while the durable store — which may\n * legitimately hold a flavour picked elsewhere — is machine-wide. Only a\n * literal `off` in storage proves the user (or another window) actually turned\n * the flavour off, which is the case the cross-tab restore must act on\n * (audit F4). */\nexport function readExplicitFlavorOff(): boolean {\n try {\n return localStorage.getItem(FLAVOR_STORAGE_KEY) === 'off'\n } catch {\n return false\n }\n}\n\n/** Persist the flavour choice (storage failures keep the in-memory state). */\nexport function writeFlavor(choice: FlavorChoice): void {\n try {\n localStorage.setItem(FLAVOR_STORAGE_KEY, choice)\n } catch {\n /* in-memory state still applies for this tab */\n }\n}\n\n/** Remember a built-in preference (system/light/dark) whenever the runtime is\n * not on a Catppuccin flavour, so switching the plugin off restores the\n * user's pre-plugin choice instead of dropping them onto 'system'. The boot\n * preference is the settings-document value, so this survives Desktop's\n * per-launch port churn without joining the durable state schema. */\nexport function rememberBuiltinPreference(preference: string): void {\n if ((CATPPUCCIN_FLAVOR_VALUES as readonly string[]).includes(preference)) return\n try {\n localStorage.setItem(RESTORE_STORAGE_KEY, preference)\n } catch {\n /* nothing to restore later — 'off' falls back to 'system' */\n }\n}\n\n/** The preference to restore when turning the flavour off (default: system). */\nexport function readRestoredPreference(): 'system' | 'light' | 'dark' {\n try {\n const raw = localStorage.getItem(RESTORE_STORAGE_KEY)\n return raw === 'light' || raw === 'dark' ? raw : 'system'\n } catch {\n return 'system'\n }\n}\n\n/** Read the persisted auto-check flag (absent means the shipped default: on). */\nexport function readAutoCheck(): boolean {\n try {\n const raw = localStorage.getItem(AUTO_CHECK_KEY)\n return raw === null ? DEFAULT_AUTO_CHECK : raw === 'true'\n } catch {\n return DEFAULT_AUTO_CHECK\n }\n}\n\n/** Persist the auto-check flag. */\nexport function writeAutoCheck(value: boolean): void {\n try {\n localStorage.setItem(AUTO_CHECK_KEY, String(value))\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/** Read the persisted update channel (absent means `latest`). */\nexport function readUpdateChannel(): UpdateChannel {\n try {\n return localStorage.getItem(UPDATE_CHANNEL_KEY) === 'beta' ? 'beta' : DEFAULT_UPDATE_CHANNEL\n } catch {\n return DEFAULT_UPDATE_CHANNEL\n }\n}\n\n/** Persist the update channel. */\nexport function writeUpdateChannel(value: UpdateChannel): void {\n try {\n localStorage.setItem(UPDATE_CHANNEL_KEY, value)\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/** Read the persisted token overrides (unparseable/absent → empty map).\n *\n * Sanitized on read (`sanitizeOverrides`, the same guard the settings document\n * goes through) so localStorage and the durable section always have the SAME\n * shape. Without it a key that is not a `--` token (e.g. `dsw-static-blue-500`\n * typed without the dashes) lives in localStorage only: the hydration compares\n * the two shapes, sees a difference, and \"the document wins\" overwrites the\n * entry — the user's row vanished a debounce-beat after it was typed. */\nexport function readOverrides(): Record<string, string> {\n try {\n const raw = localStorage.getItem(OVERRIDES_KEY)\n if (raw === null) return {}\n return sanitizeOverrides(JSON.parse(raw))\n } catch {\n return {}\n }\n}\n\n/** Persist the token overrides (storage failures keep the in-memory state). */\nexport function writeOverrides(value: Record<string, string>): void {\n try {\n localStorage.setItem(OVERRIDES_KEY, JSON.stringify(value))\n } catch {\n /* in-memory state still applies */\n }\n}\n\nlet overridesSnapshotCache: Record<string, string> | null = null\n\n/** Stable-reference snapshot of the token overrides for `useSyncExternalStore`.\n * `readOverrides()` parses localStorage and returns a NEW object per call —\n * a React store whose getSnapshot returns a fresh reference every time loops\n * forever (\"Maximum update depth exceeded\") and the settings row crashes.\n * This accessor returns the SAME object while the persisted map is unchanged\n * and swaps only when the content actually differs. */\nexport function overridesSnapshot(): Record<string, string> {\n const next = readOverrides()\n const cached = overridesSnapshotCache\n if (cached !== null && JSON.stringify(cached) === JSON.stringify(next)) return cached\n overridesSnapshotCache = next\n return next\n}\n\n/** Read the persisted shiki style (absent means the shipped default). */\nexport function readShikiStyle(): ShikiStyle {\n try {\n return localStorage.getItem(SHIKI_STYLE_KEY) === 'italic-comments' ? 'italic-comments' : DEFAULT_SHIKI_STYLE\n } catch {\n return DEFAULT_SHIKI_STYLE\n }\n}\n\n/** Persist the shiki style. */\nexport function writeShikiStyle(value: ShikiStyle): void {\n try {\n localStorage.setItem(SHIKI_STYLE_KEY, value)\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/**\n * Does this host ship the menu blur that makes a translucent menu surface work?\n *\n * `--dsw-specific-menu` only became translucent together with the blur: upstream\n * 0.1.7-alpha.1 changed it from `var(--dsw-alias-bg-layer-3)` to a literal\n * 58%/50% neutral AND introduced `--dsw-menu-backdrop-filter: blur(40px)\n * saturate(150%)` in the same release (checked against the 0.1.6-alpha.1 tag,\n * which still has the opaque ladder step and no blur token). On an older host —\n * `latest` is still the 0.1.5 line — the same fill would be *plain*\n * transparency: the transcript would show through the menu with nothing to\n * soften it, and the token also paints panels that carry text (queue dock, todo\n * panel, goal bar, job list, stat dialog, …).\n *\n * Read through <body>'s computed style, where ui-theme declares both tokens.\n * `--dsw-mask-blur` is probed first as a sanity check: it exists in every host\n * we support, so an empty read means the theme stylesheet is not in the cascade\n * yet (or the environment exposes no computed styles). Answering \"false\" then\n * is the safe side — the opaque fill is correct for every host that predates\n * the blur.\n */\nexport function hostHasMenuBlur(): boolean {\n if (typeof getComputedStyle !== 'function') return false\n const body = document.body\n if (body === null) return false\n const styles = getComputedStyle(body)\n if (styles.getPropertyValue('--dsw-mask-blur').trim() === '') return false\n return styles.getPropertyValue('--dsw-menu-backdrop-filter').trim() !== ''\n}\n\n/**\n * Token patch for `--dsw-specific-menu`: the flavour's translucent fill stands\n * where the host declares the matching blur (the value lives in palettes.ts),\n * and the opaque pre-0.1.7 ladder step is injected everywhere else. Applied\n * BEFORE the user overrides, so an explicit `--dsw-specific-menu` in the\n * overrides editor still wins.\n */\nexport function menuSurfaceFor(hostHasBlur: boolean): Record<string, string> {\n return hostHasBlur ? {} : { '--dsw-specific-menu': 'var(--dsw-alias-bg-layer-3)' }\n}\n\n/** Built-in preferences the Appearance row can explicitly pick. */\nconst BUILTIN_PREFERENCES = ['light', 'dark', 'system'] as const\ntype BuiltinPreference = (typeof BUILTIN_PREFERENCES)[number]\n\nfunction isBuiltinPreference(value: string): value is BuiltinPreference {\n return (BUILTIN_PREFERENCES as readonly string[]).includes(value)\n}\n\n/** Whether an observed built-in preference wins over the persisted flavour.\n * Only a light/dark value the user explicitly picked in THIS session — the\n * recorded `liveBuiltinPick` from the setTheme wrapper — wins. Values adopted\n * from the settings document at boot/reload (`livePick` null) never win\n * (issue #6: a doc persisted as `ui-theme.preference: light` was mistaken for\n * a user choice and buried the flavour on every refresh/restart), and\n * \"system\" never wins: while a flavour is on, the Catppuccin row is the\n * active controller and the Appearance row must not bury the persisted\n * choice. A user's explicit light/dark pick still wins immediately (matching\n * livePick) and choosing \"off\" in the Catppuccin row restores it. */\nexport function builtinPickWins(\n preference: string,\n livePick: BuiltinPreference | null,\n): boolean {\n if (preference !== 'light' && preference !== 'dark') return false\n return preference === livePick\n}\n\n/** Required services: slots + locale (settings rows) and theme (register +\n * switch). The durable settings transport is NOT a hard dependency: which\n * service provides it depends on the host version (issue #15 — 0.1.7-alpha.1\n * replaced `settingsScope` with `configForms`), so `createDurableScope`\n * binds whichever one appears through its own optional injections. Listing\n * either name here would leave the plugin permanently pending on the other\n * half of the installed base. */\nexport const inject = ['slots', 'locale', 'theme']\n\n/**\n * Register the Catppuccin dictionaries, the flavour themes (lazy — item JJ:\n * only the active flavour is registered, the rest on first selection), and\n * the settings rows.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Bilingual balance is enforced by the typed register call (zh + en);\n // ja/ko/es/fr/de ride the untyped language-pack form and are registered\n // as selectable languages (fallback chain → en) so the dictionaries are\n // reachable without an external language pack (item CC).\n //\n // Every call rides `tolerantRegistration` (issue #23): a peer language pack\n // (dsh-locale-pack, …) that already owns a BCP 47 id makes `addLanguage`\n // throw `locale \"ja\" is already registered`, and a raw throw here fails\n // THIS entry → the whole web boot aborts → the desktop's crash rescue\n // disables every third-party plugin. A skipped registration costs nothing:\n // our dictionaries still land (they register into our OWN namespace), and\n // the id collision only means the peer's language entry already stands.\n ctx.effect(() => {\n const disposers = [\n tolerantRegistration(() => ctx.locale.register(NS, { zh, en })),\n tolerantRegistration(() => ctx.locale.register(NS, 'ja', ja)),\n tolerantRegistration(() => ctx.locale.register(NS, 'ko', ko)),\n tolerantRegistration(() => ctx.locale.register(NS, 'es', es)),\n tolerantRegistration(() => ctx.locale.register(NS, 'fr', fr)),\n tolerantRegistration(() => ctx.locale.register(NS, 'de', de)),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'ja', label: '日本語', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'ko', label: '한국어', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'es', label: 'Español', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'fr', label: 'Français', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'de', label: 'Deutsch', fallback: 'en' })),\n ]\n return () => {\n for (const dispose of disposers) dispose()\n }\n }, 'catppuccin: dictionaries')\n\n const theme = ctx.get('theme') as ThemeRuntime\n\n // Lazy theme registration (item JJ): at most the flavour currently in use\n // is registered; selecting a flavour registers it on demand and the fiber\n // disposer releases every registration. Overrides (item K) and the shiki\n // style (item M) are read at registration time, so a preference change\n // re-registers the active flavour with the merged tokens.\n const themeDisposers = new Map<string, () => void>()\n const registerThemeFor = (flavor: CatppuccinFlavorInfo): void => {\n if (themeDisposers.has(flavor.themeId)) return\n // Flavour id for the shiki token lookup: themeId is \"catppuccin-latte\"\n // → key is \"latte\".\n const flavorId = flavor.themeId.replace('catppuccin-', '') as CatppuccinFlavorId\n const shiki = SHIKI_TOKENS[flavorId][readShikiStyle()]\n // Tolerant (issue #23): `theme.register` throws `theme \"…\" is already\n // registered` when another instance of this plugin owns the id (a\n // duplicate install). One reachable path runs it synchronously\n // (applyScopeSnapshot → reapplyThemePrefs, inside the boot effect), so a\n // raw throw could fail the entry; the others (the deferred restore\n // microtask, the storage event) would turn into uncaught errors. A skip\n // is right either way: the theme exists (the peer's copy), `setTheme`\n // below still works, and the no-op disposer memoizes the skip so we do\n // not re-attempt on every override change.\n const disposer = tolerantRegistration(() => theme.register({\n id: flavor.themeId,\n colorScheme: flavor.colorScheme,\n tokens: {\n ...flavor.tokens,\n ...shiki,\n // Host-shape patch (0.1.7 vs the 0.1.5 latest line): keep the menu\n // surface readable on hosts without the menu blur. Below the user\n // overrides on purpose — see menuSurfaceFor().\n ...menuSurfaceFor(hostHasMenuBlur()),\n ...readOverrides(),\n } as ThemeTokens,\n }))\n themeDisposers.set(flavor.themeId, disposer)\n }\n const ensureThemeRegistered = (themeId: string): void => {\n const flavor = flavorInfo(themeId)\n if (flavor !== undefined) registerThemeFor(flavor)\n }\n const disposeThemeRegistrations = (): void => {\n for (const dispose of themeDisposers.values()) dispose()\n themeDisposers.clear()\n }\n ctx.effect(() => disposeThemeRegistrations, 'catppuccin: flavour theme disposers')\n\n // The glass layer: a toggleable glassmorphism skin on top of the Catppuccin\n // themes. It owns its lifecycle (enable flag + knobs persist in\n // localStorage as the in-browser cache; the durable copy is the settings\n // document hydrated/pushed below; every effect is released with this fiber).\n // It is created before the boot-restore effect so hydration can overlay the\n // persisted glass state onto the layer.\n const glass = new GlassLayer(ctx)\n\n // The official settings transport for the Catppuccin durable state. Which\n // seam it is depends on the host version (0.1.7-alpha.1 replaced the\n // `settingsScope` namespace binding with the `configForms` entry form), so\n // the facade picks whichever service the host provides and never blocks\n // this fiber on it. The document is the source of truth; the scope derives\n // from the shared mirror and never blocks on the transport.\n const scope = createDurableScope(ctx)\n\n // The current durable snapshot: flavour from the localStorage cache (the\n // authoritative write target of the settings row) plus the glass layer's\n // remote state and the preference fields. Passed to the debounced scope\n // persist by reference so the flush always captures the freshest values.\n const buildLocalState = (): CatppuccinState => ({\n version: STATE_VERSION,\n // `FlavorChoice` widens to `string` (palettes carry `themeId: string`), but\n // the runtime value is always one of the four theme ids or `off` — the\n // same set as `FlavorValue`, guarded by tests/state.spec.ts.\n flavor: readFlavor() as FlavorValue,\n glass: glass.getRemoteState(),\n autoCheck: readAutoCheck(),\n updateChannel: readUpdateChannel(),\n overrides: readOverrides(),\n shikiStyle: readShikiStyle(),\n })\n\n // Preference pub/sub: the settings rows read/write autoCheck, channel,\n // overrides and shikiStyle through localStorage; any change re-renders the\n // rows (emitPrefs) and the conflict counter feeds the update row's\n // \"另一窗口已更新\" banner (item X).\n const prefsListeners = new Set<() => void>()\n const emitPrefs = (): void => {\n for (const listener of prefsListeners) listener()\n }\n let conflictCount = 0\n const conflictListeners = new Set<() => void>()\n const emitConflict = (): void => {\n conflictCount += 1\n for (const listener of conflictListeners) listener()\n }\n\n // Re-register the active flavour after an override/shiki-style change so\n // the new token mix applies (the disposed registration is replaced by one\n // carrying the merged overrides).\n const reapplyThemePrefs = (): void => {\n const active = theme.getTheme().preference\n const flavor = flavorInfo(active)\n if (flavor === undefined || !themeDisposers.has(flavor.themeId)) return\n disposeThemeRegistrations()\n registerThemeFor(flavor)\n }\n\n // Debounced push of the current local state into the settings document.\n // When the scope is not usable (memory mode / absent transport) the write\n // is skipped entirely — localStorage stays the only store, exactly the\n // pre-0.5.0 route-missing fallback. The write is read-side guarded (item\n // C/X): a flush whose base revision the document moved past returns\n // `stale`, the local change is abandoned, and the remote state is\n // re-adopted + surfaced in the update row.\n let lastWrittenSection: CatppuccinSettingsSection | undefined\n let handleStaleConflict: (() => void) | undefined\n // R2 (2026-10-10 review): whether a local change was made while the durable\n // scope was NOT yet usable — the boot window, when the settings service\n // lands late or its first snapshot is still in flight. Such a change has no\n // channel to be pushed through yet, and the FIRST snapshot the scope later\n // resolves may describe an OLDER document — without this flag the hydration\n // below would \"adopt the document\" and silently roll the change back. The\n // flag makes the first usable snapshot push the local state instead; a\n // section that already equals the local state makes the queued write a\n // noop, so the ordinary boot path pays nothing.\n let pendingLocalPush = false\n // The revision the pending write is based on, captured when the change is\n // SCHEDULED (audit F2): reading it at flush time made the read-side staleness\n // guard compare a revision with itself — both reads sit in one synchronous\n // block — so `'stale'` was unreachable and an external edit inside the\n // debounce window was silently overwritten. One capture per burst.\n const baseRevisionTracker = createBaseRevisionTracker()\n const queuePersist = (): void => {\n // Marked at SCHEDULE time, not at flush time: the dangerous window is\n // \"change happened before the scope first became usable\", which includes\n // the debounce beat BEFORE the flush runs (a scope that turns ready\n // inside that beat would hydrate and roll the change back before the\n // flush ever sees it).\n if (!isScopeUsable(scope.getSnapshot())) pendingLocalPush = true\n baseRevisionTracker.capture(() => scope.getSnapshot().revision)\n scheduleDurablePersist(persistLocal)\n }\n const persistLocal = (): void => {\n // Consume the base first: a bail-out (unusable scope) must not leave it\n // behind for the next burst.\n const baseRevision = baseRevisionTracker.take()\n const snapshot = scope.getSnapshot()\n if (!isScopeUsable(snapshot)) return\n const state = buildLocalState()\n void persistStateToScope(scope, state, { baseRevision, lastWrittenSection }).then((outcome) => {\n if (outcome === 'written') {\n lastWrittenSection = settingsSectionFromState(state)\n } else if (outcome === 'stale') {\n emitConflict()\n handleStaleConflict?.()\n }\n })\n }\n\n // Auto-check (item H): the last verdict the periodic checker stored (the\n // update row surfaces it on mount) plus the arm hook the preference\n // setter re-invokes on toggle (the timers themselves live in the restore\n // effect below, so they die with the fiber).\n const AUTO_CHECK_BOOT_DELAY_MS = 3000\n const AUTO_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000\n let lastAutoResult: UpdateCheckPayload | null = null\n let armAutoCheck: (() => void) | undefined\n\n // Restore the persisted choice and defend it against the built-in\n // Appearance scope's `adopt()`. Two stores feed the desired flavour:\n // localStorage (the in-browser cache — instant at boot and the cross-tab\n // `storage` bus) and the durable store (the source of truth — required\n // because localStorage is per-browser and per-origin while the DSH home is\n // machine-wide; see `src/state.ts`).\n //\n // The re-assert is not a fixed boot window. The built-in ThemeRuntime's\n // `adopt()` re-applies the settings-document preference on every settings\n // reload — and switching the model always reloads the settings document —\n // writing \"system\" when `ui-theme.preference` was never written, or the\n // persisted light/dark when the document holds one. adopt() writes the\n // runtime preference directly and bypasses setTheme, so the setTheme wrapper\n // below is the one seam that tells explicit picks apart: we restore our\n // flavour whenever the runtime preference is NOT a built-in value the user\n // clicked in the Appearance row THIS session, and choosing \"off\" in the\n // Catppuccin row clears the persisted flavour before the switch so this\n // guard does not fight it.\n ctx.effect(() => {\n // Session-live record of the user's last EXPLICIT built-in pick, kept by\n // the setTheme wrapper below. The wrapper is the only seam that\n // distinguishes \"the user clicked light/dark/system in the Appearance\n // row\" from \"ThemeRuntime.adopt() copied the settings document's value\n // at boot/reload\" — adopt() writes the preference directly and never goes\n // through setTheme, so a doc-adopted light/dark leaves this null and the\n // guard below cannot mistake it for a user choice. Picking a Catppuccin\n // flavour (or the wrapper's own flavour restore) clears the record.\n let liveBuiltinPick: BuiltinPreference | null = null\n const originalSetTheme = theme.setTheme\n // Named on purpose (R1, 2026-10-10 review): the cleanup below may only\n // restore the original while the method is still OUR wrapper. Another\n // extension replacing it afterwards owns the slot by then, and an\n // unconditional write-back of the original would silently unhook it.\n const restoreGuardSetTheme = (id: string): void => {\n liveBuiltinPick = isBuiltinPreference(id) ? id : null\n originalSetTheme.call(theme, id)\n }\n theme.setTheme = restoreGuardSetTheme\n\n // Issue #10: a synchronous setTheme inside a theme/change dispatch\n // re-enters publish() — the ThemePresenter (registered after us) then\n // applies the STALE snapshot carried by the OUTER dispatch last, so the\n // DOM ends up dark/system while the runtime preference is the flavour.\n // Defer the restore out of the current dispatch (microtask) and re-check\n // at run time, so the flavour's setTheme is always the LAST event the\n // presenter sees. A single in-flight restore coalesces repeated\n // observations (boot, adopt() reloads, storage echoes).\n let restorePending = false\n // `desired` is widened to string on purpose: the SAME deferred path also\n // carries the built-in restore (audit F4) — when the persisted choice went\n // 'off' somewhere else, the theme to apply is a built-in preference\n // (`system`/`light`/`dark`), not a flavour id.\n const scheduleRestore = (desired: string): void => {\n if (restorePending) return\n restorePending = true\n queueMicrotask(() => {\n restorePending = false\n const preference = theme.getTheme().preference\n if (preference === desired) return\n // Re-check the guard at run time: a newer explicit built-in pick\n // (or a newer event) still wins over the persisted flavour.\n if (builtinPickWins(preference, liveBuiltinPick)) return\n // Lazy registration (item JJ): the theme must exist before setTheme.\n ensureThemeRegistered(desired)\n try {\n theme.setTheme(desired)\n } catch {\n // Theme not registered yet — a later theme/change re-runs applyDesired.\n }\n })\n }\n\n const applyDesired = (): void => {\n // Record the built-in preference on every non-flavour observation (boot,\n // adopt() reloads, explicit Appearance changes) BEFORE any re-assert, so\n // 'off' below can hand the user back exactly what they had.\n rememberBuiltinPreference(theme.getTheme().preference)\n const desired = readFlavor()\n if (desired === 'off') {\n // The persisted choice is off — but this session may still be rendering\n // a Catppuccin flavour (another window or the settings document turned\n // it off). Hand the user back their built-in preference, exactly like\n // the row's own `select('off')` path. Gated on an EXPLICIT 'off' in\n // localStorage (audit F4): an empty storage may just mean this\n // browser/origin never chose, so the absence of a value is NOT a choice\n // and the durable store — which may legitimately restore a flavour — is\n // authoritative. Without that gate we would fight the document on every\n // boot of a fresh origin.\n const preference = theme.getTheme().preference\n if (readExplicitFlavorOff() && flavorFromThemeId(preference) !== 'off') {\n scheduleRestore(readRestoredPreference())\n }\n return\n }\n const preference = theme.getTheme().preference\n if (preference === desired) return\n // A built-in preference only wins if the user explicitly picked it in\n // THIS session (matching liveBuiltinPick). \"system\" and boot/adopt()\n // values adopted from the settings document (liveBuiltinPick null) are\n // stale for the plugin — the Catppuccin row choice is newer than the\n // document's light/dark, so restore the flavour then.\n if (builtinPickWins(preference, liveBuiltinPick)) return\n scheduleRestore(desired)\n }\n applyDesired()\n const disposer = ctx.on('theme/change', applyDesired)\n const onStorage = (event: StorageEvent): void => {\n if (event.key !== FLAVOR_STORAGE_KEY) return\n const next = readFlavor()\n if (next !== 'off') {\n ensureThemeRegistered(next)\n try {\n theme.setTheme(next)\n } catch {\n /* unknown persisted value — keep the current theme */\n }\n return\n }\n // Another window turned the flavour off (audit F4): this tab must land on\n // the built-in preference too, or it keeps rendering Catppuccin while the\n // persisted choice — and the settings row of the other window — say off.\n if (flavorFromThemeId(theme.getTheme().preference) === 'off') return\n try {\n theme.setTheme(readRestoredPreference())\n } catch {\n /* keep the current theme rather than dropping the user into nothing */\n }\n }\n window.addEventListener('storage', onStorage)\n\n // Any glass change (enable flag or knob) coalesces into one durable write.\n const offGlass = glass.subscribe(() => {\n queuePersist()\n })\n\n // Hydrate the durable source of truth without blocking paint. The scope\n // derives from the shared settings mirror (no wire read of its own), so\n // this is sync once the mirror has resolved; if it arrives later, the\n // subscription below catches it — the localStorage fast path keeps\n // working in the meantime.\n //\n // The hydration is echo-safe: the Host folds our own committed writes\n // back into the mirror, and when the echoed section equals the local\n // state (the normal case after a change we just persisted) we skip the\n // write-back. A section that differs is an external edit (another\n // surface, a hand-edited document, a reload) — the document wins.\n const applyScopeSnapshot = (): void => {\n const snapshot = scope.getSnapshot()\n const state = durableStateFromSnapshot(snapshot)\n if (state === null) return // loading / memory / absent — localStorage-only\n const local = buildLocalState()\n // R2: a change made before the scope first became usable wins over the\n // first usable snapshot (see `pendingLocalPush`). Re-queue it and skip\n // this adoption pass entirely — the queued write is a noop when the\n // section already equals the local state.\n if (pendingLocalPush) {\n pendingLocalPush = false\n queuePersist()\n return\n }\n // The channel owns the \"does the document hold a user layer yet?\" test:\n // the new form's `user` is an empty object until someone writes, while\n // the legacy document omits it entirely.\n if (!scope.hasUserLayer(snapshot)) {\n // No user layer in the document yet: this session's localStorage\n // choice is newer than the shipped defaults the document resolves\n // to, so push it into the document (the upgrade path for a\n // localStorage-only session predating the settings migration).\n if (!isDefaultState(local)) queuePersist()\n return\n }\n // A document holding unpersistable override entries (a hand-edited key\n // that is not a `--` token) can never compare equal to the sanitized\n // local shape, so every publish would re-run this adoption forever.\n // Adopt, then push the cleaned map back once so the document converges\n // (audit F7).\n if (hasUnpersistableOverrides((snapshot.value as { overrides?: unknown } | undefined)?.overrides)) {\n queuePersist()\n }\n // A document the user wrote wins over the local cache, but echoes of\n // our own committed writes are skipped (they equal the local state).\n if (settingsSectionsEqual(\n settingsSectionFromState(local),\n settingsSectionFromState(state),\n )) return // our own echo — nothing to adopt\n writeFlavor(state.flavor)\n glass.applyRemote(state.glass)\n writeAutoCheck(state.autoCheck)\n writeUpdateChannel(state.updateChannel)\n writeOverrides(state.overrides)\n writeShikiStyle(state.shikiStyle)\n emitPrefs()\n reapplyThemePrefs()\n applyDesired()\n }\n applyScopeSnapshot()\n const offScope = scope.subscribe(applyScopeSnapshot)\n\n // Auto-check (item H): warm the Host's verdict cache at boot and every\n // 6 hours while the preference is on. The row surfaces the last result\n // and the Host cache keeps re-opens instant; failures stay uncached so\n // the next cycle retries for real.\n const runAutoCheck = async (): Promise<void> => {\n try {\n const response = await fetch(`${UPDATE_ROUTE_PATH}?channel=${readUpdateChannel()}`, {\n headers: { accept: 'application/json' },\n // R3: same client-side cap as the manual check — a periodic probe\n // must never pile up behind a wedged host.\n signal: AbortSignal.timeout(UPDATE_CHECK_CLIENT_TIMEOUT_MS),\n })\n if (response.ok) lastAutoResult = await response.json() as UpdateCheckPayload\n } catch {\n /* best-effort; the row's retry discipline covers the user-visible UX */\n }\n }\n let bootTimer: number | undefined\n let intervalTimer: number | undefined\n const armAutoCheckImpl = (): void => {\n window.clearTimeout(bootTimer)\n window.clearInterval(intervalTimer)\n if (!readAutoCheck()) return\n bootTimer = window.setTimeout(() => { void runAutoCheck() }, AUTO_CHECK_BOOT_DELAY_MS)\n intervalTimer = window.setInterval(() => { void runAutoCheck() }, AUTO_CHECK_INTERVAL_MS)\n }\n armAutoCheck = armAutoCheckImpl\n armAutoCheckImpl()\n\n handleStaleConflict = () => applyScopeSnapshot()\n\n return () => {\n offScope()\n offGlass()\n disposer()\n window.removeEventListener('storage', onStorage)\n window.clearTimeout(bootTimer)\n window.clearInterval(intervalTimer)\n cancelDurablePersist()\n handleStaleConflict = undefined\n armAutoCheck = undefined\n // Undo the setTheme wrapper so a stopped plugin leaves the runtime as\n // it found it — but only while the wrapper is still ours (R1): if\n // another extension replaced it after us, that replacement is the\n // current owner and force-writing the original back would unhook it\n // without a trace.\n if (theme.setTheme === restoreGuardSetTheme) {\n theme.setTheme = originalSetTheme\n } else {\n console.warn('[dsh-catppuccin] theme.setTheme was replaced by another extension; leaving it in place')\n }\n }\n }, 'catppuccin: theme restore')\n\n const injected = (): CatppuccinRowInjected => ({\n themes: CATPPUCCIN_FLAVORS.map((flavor) => ({\n id: flavor.themeId,\n label: flavor.label,\n accent: flavor.accent,\n })),\n current: () => {\n const pref = theme.getTheme().preference\n return flavorFromThemeId(pref)\n },\n subscribe: (listener) => ctx.on('theme/change', listener),\n select: (choice: FlavorChoice) => {\n if (choice === 'off') {\n // Restore the built-in preference the user had before the flavour\n // ('system' when nothing was recorded). Persist the abandoned choice\n // BEFORE setTheme: setTheme emits theme/change synchronously, so the\n // restore guard must already read `off` here and not re-assert the\n // previous flavour.\n writeFlavor('off')\n // Wrapped like every other setTheme call (issue #23 audit): a throw\n // here used to escape into the row's click handler; keep the current\n // theme instead of dropping the user into nothing.\n try {\n theme.setTheme(readRestoredPreference())\n } catch {\n /* keep the current theme rather than dropping the user into nothing */\n }\n queuePersist()\n return\n }\n const flavor = flavorInfo(choice)\n if (!flavor) return\n // Persist first so the restore guard (a theme/change listener) sees the\n // new flavour when setTheme below emits synchronously. Lazy\n // registration: the theme must exist before setTheme (item JJ).\n writeFlavor(flavor.themeId)\n ensureThemeRegistered(flavor.themeId)\n try {\n theme.setTheme(flavor.themeId)\n } catch {\n /* theme unavailable — keep the current one; a later theme/change retries */\n }\n queuePersist()\n },\n overrides: overridesSnapshot,\n setOverrides: (overrides: Record<string, string>) => {\n writeOverrides(overrides)\n emitPrefs()\n reapplyThemePrefs()\n queuePersist()\n },\n shikiStyle: () => readShikiStyle(),\n setShikiStyle: (style: ShikiStyle) => {\n writeShikiStyle(style)\n emitPrefs()\n reapplyThemePrefs()\n queuePersist()\n },\n subscribePrefs: (listener: () => void) => {\n prefsListeners.add(listener)\n return () => { prefsListeners.delete(listener) }\n },\n })\n\n // Every row registration rides `tolerantRegistration` (issue #23): the\n // callback runs SYNCHRONOUSLY when the slot is already declared (the\n // renderer's documented contract), so a duplicate id at the same priority\n // (`list slot \"…\" already has an entry with id \"…\"`, e.g. a duplicate\n // install) would otherwise throw straight through apply() and fail the\n // boot. A skipped row costs nothing: the occupant is the same row.\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin',\n order: 20,\n locale: NS,\n inject: injected,\n }, CatppuccinRow)))\n\n const glassInjected = (): GlassRowInjected => ({\n getState: () => glass.getSnapshot(),\n subscribe: (listener) => glass.subscribe(listener),\n setEnabled: (enabled) => { glass.setEnabled(enabled) },\n setMode: (mode) => { glass.setMode(mode) },\n setBlur: (blur) => { glass.setBlur(blur) },\n setFrost: (frost) => { glass.setFrost(frost) },\n setBrightness: (brightness) => { glass.setBrightness(brightness) },\n resetDefaults: () => { glass.resetDefaults() },\n })\n\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin-glass',\n order: 21,\n locale: NS,\n inject: glassInjected,\n }, GlassRow)))\n\n // Update check: the Host owns the npm lookup (Node fetch, no CORS); the row\n // only fetches the same-origin route and renders the verdict. Upgrade stays\n // a terminal action — the row just surfaces the CLI command.\n const updateInjected = (): UpdateRowInjected => ({\n check: async (channel: UpdateChannel) => {\n try {\n const response = await fetch(`${UPDATE_ROUTE_PATH}?channel=${channel}`, {\n headers: { accept: 'application/json' },\n // R3 (2026-10-10 review): cap the host hop. The route's own registry\n // lookup is capped at 8s (UPDATE_FETCH_TIMEOUT_MS), so this budget\n // only bites when the host process itself stopped answering —\n // without it the row's `checking` phase (and its disabled button)\n // could stay pinned forever. The abort lands in the catch below as\n // the same `network.local` as any other failed hop.\n signal: AbortSignal.timeout(UPDATE_CHECK_CLIENT_TIMEOUT_MS),\n })\n return await response.json() as UpdateCheckPayload\n } catch {\n return { ok: false, code: 'network.local', error: 'network.local' }\n }\n },\n autoCheck: () => readAutoCheck(),\n setAutoCheck: (value: boolean) => {\n writeAutoCheck(value)\n emitPrefs()\n queuePersist()\n armAutoCheck?.() // re-arm the boot/periodic timers on toggle\n },\n channel: () => readUpdateChannel(),\n setChannel: (channel: UpdateChannel) => {\n writeUpdateChannel(channel)\n emitPrefs()\n queuePersist()\n },\n subscribePrefs: (listener: () => void) => {\n prefsListeners.add(listener)\n return () => { prefsListeners.delete(listener) }\n },\n lastAutoResult: () => lastAutoResult,\n subscribeConflict: (listener: () => void) => {\n conflictListeners.add(listener)\n return () => { conflictListeners.delete(listener) }\n },\n conflictCount: () => conflictCount,\n // Timestamps must follow the interface language, not the browser locale\n // (`toLocaleString()` with no argument silently uses the latter).\n activeLocale: () => ctx.locale.getLocale().active,\n subscribeLocale: (listener: () => void) => ctx.locale.subscribe(listener),\n })\n\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin-update',\n order: 22,\n locale: NS,\n inject: updateInjected,\n }, UpdateRow)))\n\n // Feedback & support row (2026-10-11): closes the section with two static\n // GitHub links — the issue tracker and the repo (the star ask). Pure copy,\n // so it registers WITHOUT an inject factory (only the locale seat); live\n // edits to the URLs belong in LinksRow.tsx. Rendered in both homes: the\n // General section here and the plugin detail card below.\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin-links',\n order: 23,\n locale: NS,\n }, LinksRow)))\n\n // Plugins-page card: the settings section on this plugin's OWN detail page in\n // the Plugin manager (DSH >= 0.2.0-rc.2). Three things about this\n // registration are contracts, not style (see `src/client/detail-card.tsx`):\n // - `key` is the BUNDLE PACKAGE NAME, because the page dispatches with\n // `{ entryKey: pkg.name }` — NOT `CATPPUCCIN_ENTRY_ID`, which keys the\n // settings namespace;\n // - the section exists only while this registration does, so `whileServed`\n // withdraws it with the namespace instead of leaving an empty block;\n // - the face is the SAME three factories the General rows use, so the second\n // home shares the durable section rather than a copy of it.\n // `whileServed` is guarded because not every host past 0.1.7 serves it, and\n // `slots.inject` waits for the slot's DECLARATION — a host without the Plugin\n // manager never fires it (no throw, no pending state).\n const detailInjected = (): CatppuccinDetailCardInjected => ({\n flavor: injected(),\n glass: glassInjected(),\n update: updateInjected(),\n })\n\n ctx.inject(['configForms'], (formsCtx) => {\n const forms = formsCtx.configForms\n if (typeof forms.whileServed !== 'function') return\n return forms.whileServed([CATPPUCCIN_ENTRY_ID], () => ctx.slots.inject(\n 'plugins.bundle.config',\n () => tolerantRegistration(() => ctx.slots.register({\n name: 'plugins.bundle.config',\n key: PACKAGE_NAME,\n locale: NS,\n inject: detailInjected,\n }, CatppuccinDetailCard)),\n ))\n })\n}"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["Segmented","useSyncExternalStore","useState","useRef","css","useState","useRef","useSyncExternalStore","useState","useSyncExternalStore","useRef"],"sources":["../src/client/CatppuccinRow.tsx","../src/client/glass/glass-seams.ts","../src/client/glass/glass-css.gen.ts","../src/state.ts","../src/client/glass/glass-layer.ts","../src/client/glass/glass-row.tsx","../src/client/LinksRow.tsx","../src/client/UpdateRow.tsx","../src/client/detail-card.tsx","../src/client/locales.ts","../src/client/palettes.ts","../src/client/shiki-tokens.ts","../src/update-check.ts","../src/registration-tolerance.ts","../src/client/state-sync.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Catppuccin settings row — one General-section preference row listing the\n * four flavour themes plus a \"follow system\" (off) choice. Selecting a\n * flavour calls the injected `select`, which switches the official\n * ThemeRuntime and persists the choice. The row subscribes to `theme/change`\n * so the highlighted flavour tracks the live preference.\n *\n * Beyond the flavour pick the row carries:\n * - per-flavour localized subtitles (item DD) under the button labels;\n * - the shiki style pick (item M, `default` / `italic-comments`);\n * - a collapsible power-user token-override editor (item K);\n * - a \"?\" help affordance (item J) — no framework tooltip API exists in\n * dsh-client-ui-slots yet, so the help text rides the native `title`\n * attribute plus an accessible name.\n */\nimport { useRef, useState, useSyncExternalStore } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { FlavorChoice } from './index.ts'\nimport type { ShikiStyle } from '../state.ts'\nimport type { CatppuccinKey } from './locales.ts'\n\n/** One flavour button shown by the row. */\nexport interface CatppuccinFlavorButton {\n /** Theme id registered into ThemeRuntime. */\n id: string\n /** Display label. */\n label: string\n /** Accent colour for the swatch. */\n accent: string\n}\n\n/** Injected business face of the row (assembled in apply). */\nexport interface CatppuccinRowInjected {\n /** The four flavours, in display order. */\n themes: readonly CatppuccinFlavorButton[]\n /** Current choice (`off` when a Catppuccin theme is not active). */\n current: () => FlavorChoice\n /** Subscribe to theme preference changes. Returns the disposer. */\n subscribe: (listener: () => void) => () => void\n /** Switch the theme and persist the choice (`off` reverts to system). */\n select: (choice: FlavorChoice) => void | Promise<void>\n /** Current user token overrides (item K). */\n overrides: () => Record<string, string>\n /** Replace the whole override map (persists + re-registers the theme). */\n setOverrides: (overrides: Record<string, string>) => void\n /** Current shiki style (item M). */\n shikiStyle: () => ShikiStyle\n /** Set the shiki style (persists + re-registers the theme). */\n setShikiStyle: (style: ShikiStyle) => void\n /** Subscribe to preference (overrides / shiki style) changes. */\n subscribePrefs: (listener: () => void) => () => void\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type CatppuccinRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'> & CatppuccinRowInjected\n\n/** 普通按钮行内样式。 */\nconst buttonBase: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 12px',\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l1)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary)',\n cursor: 'pointer',\n font: 'inherit',\n}\n\n/** 选中态按钮行内样式。 */\nconst buttonActive: React.CSSProperties = {\n ...buttonBase,\n border: '1px solid var(--dsw-alias-border-l3)',\n background: 'var(--dsw-alias-interactive-bg-active)',\n}\n\nconst inputBase: React.CSSProperties = {\n background: 'var(--dsw-alias-bg-layer-2)',\n border: '1px solid var(--dsw-alias-border-l1)',\n borderRadius: 6,\n padding: '4px 8px',\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 12,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n}\n\n/**\n * A \"?\" help affordance: an accessible button that carries the full help\n * text in the native `title` tooltip. No visual styling beyond the token\n * palette — the affordance follows the row's label colour.\n */\nfunction HelpIcon({ label, help }: { label: string; help: string }): React.JSX.Element {\n return (\n <span\n role=\"img\"\n aria-label={label}\n title={help}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n cursor: 'help',\n userSelect: 'none',\n marginLeft: 6,\n flex: 'none',\n }}\n >\n ?\n </span>\n )\n}\n\n/** The localised subtitle of one flavour button (`flavor.<id>.subtitle`);\n * null when the active locale carries no such key. */\nfunction subtitleText(buttonId: string, t: (key: CatppuccinKey) => string): string | null {\n const flavorId = buttonId.replace('catppuccin-', '')\n if (flavorId === buttonId) return null\n const key = `flavor.${flavorId}.subtitle` as CatppuccinKey\n const text = t(key)\n return text === key ? null : text\n}\n\n/** One two-sided segmented pick using the row's token colours. */\nfunction Segmented<T extends string>(props: {\n label: string\n value: T\n options: readonly { id: T; label: string }[]\n onSelect: (value: T) => void\n}): React.JSX.Element {\n const { label, value, options, onSelect } = props\n return (\n <div style={{ display: 'inline-flex', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, overflow: 'hidden' }} role=\"group\" aria-label={label}>\n {options.map((option, index) => (\n <button\n key={option.id}\n type=\"button\"\n aria-pressed={option.id === value}\n onClick={() => { onSelect(option.id) }}\n style={{\n height: 26,\n padding: '0 12px',\n border: 'none',\n borderLeft: index > 0 ? '1px solid var(--dsw-alias-border-l2)' : undefined,\n background: option.id === value ? 'var(--dsw-alias-state-business-tertiary)' : 'transparent',\n color: option.id === value ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-label-secondary)',\n fontSize: 12,\n lineHeight: '18px',\n cursor: 'pointer',\n }}\n >\n {option.label}\n </button>\n ))}\n </div>\n )\n}\n\n/**\n * Render the Catppuccin row: title, one swatch button per flavour, and a\n * follow-system button. The active flavour is highlighted; clicking a flavour\n * applies it immediately (live, no restart) and persists the choice.\n * @param props - composed slot props.\n * @returns the row element tree.\n */\nexport function CatppuccinRow({\n t,\n themes,\n current,\n subscribe,\n select,\n overrides,\n setOverrides,\n shikiStyle,\n setShikiStyle,\n subscribePrefs,\n}: CatppuccinRowProps): React.JSX.Element {\n const choice = useSyncExternalStore(subscribe, current)\n const overrideMap = useSyncExternalStore(subscribePrefs, overrides)\n const style = useSyncExternalStore(subscribePrefs, shikiStyle)\n const [overridesOpen, setOverridesOpen] = useState(false)\n // Unsaved editor rows: key+value inputs that only enter the override map\n // once both fields hold a value (power users type tokens, so the commit is\n // live — nothing to \"save\").\n //\n // `id` is a stable React key, NOT the array index (audit F5): the fields are\n // uncontrolled, so an index key made React reuse the deleted row's DOM node\n // for the next row after a delete — the input kept showing the removed row's\n // text while the state held the surviving row's value.\n const [draftRows, setDraftRows] = useState<Array<{ id: number; key: string; value: string }>>([])\n const nextDraftId = useRef(0)\n\n // Only `--`-prefixed keys are persistable (`sanitizeOverrides` drops the\n // rest on every read — localStorage and the settings document share one\n // shape), so an incomplete key stays a draft row instead of being committed\n // and silently dropped one read later.\n const isTokenKey = (key: string): boolean => key.trim().startsWith('--')\n\n /** Commit a draft row on blur. If both fields are valid, promote to persisted;\n * otherwise keep in draft state. Item XX: changed from onChange to onBlur so\n * the row stays stable while typing—typing the first character of the value\n * previously made the draft immediately promote and unmount the input mid-edit. */\n const commitDraftKey = (index: number, key: string): void => {\n const row = draftRows[index]\n if (isTokenKey(key) && row.value.trim() !== '') {\n setOverrides({ ...overrideMap, [key.trim()]: row.value })\n setDraftRows(draftRows.filter((_, i) => i !== index))\n } else {\n setDraftRows(draftRows.map((r, i) => (i === index ? { ...r, key } : r)))\n }\n }\n\n const commitDraftValue = (index: number, value: string): void => {\n const row = draftRows[index]\n if (isTokenKey(row.key) && value.trim() !== '') {\n setOverrides({ ...overrideMap, [row.key.trim()]: value })\n setDraftRows(draftRows.filter((_, i) => i !== index))\n } else {\n setDraftRows(draftRows.map((r, i) => (i === index ? { ...r, value } : r)))\n }\n }\n\n /** Rename (or, with an empty/invalid key, delete) a persisted override. The\n * key input is uncontrolled and commits on blur: writing on every keystroke\n * repersisted the entry under each intermediate key, and an intermediate\n * key that is not a `--` token made the row delete itself mid-typing. */\n const commitPersistedKey = (oldKey: string, newKey: string): void => {\n if (newKey === oldKey) return\n const next = { ...overrideMap }\n delete next[oldKey]\n if (isTokenKey(newKey)) next[newKey.trim()] = overrideMap[oldKey]\n setOverrides(next)\n }\n\n /** Set (or, with an empty value, delete) a persisted override's value.\n *\n * Item TT: the value input is uncontrolled and commits on blur, symmetric\n * with the key input. Per-keystroke commits meant `value.trim() === ''`\n * deleted the entry while the caret was still in the field, so the row\n * (input included) unmounted mid-typing — and every keystroke additionally\n * re-registered the whole theme. Trade-off, accepted deliberately: no more\n * \"recolour as I type\" preview (intermediate values like `#89b4` are invalid\n * CSS anyway, so that preview was only ever complete on paste), and an edit\n * that never loses focus (dialog closed with Esc) is not committed.\n *\n * Known trade-off: an uncontrolled input keeps its text when the persisted\n * value changes from another tab/settings write; the row re-syncs on reopen. */\n const commitPersistedValue = (key: string, value: string): void => {\n if (value === overrideMap[key]) return\n const next = { ...overrideMap }\n if (value.trim() === '') delete next[key]\n else next[key] = value\n setOverrides(next)\n }\n\n const removePersisted = (key: string): void => {\n const next = { ...overrideMap }\n delete next[key]\n setOverrides(next)\n }\n\n return (\n <div style={{ borderBottom: '1px solid var(--dsw-alias-border-l2)', display: 'flex', flexDirection: 'column', gap: '10px', padding: '16px 0' }}>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 14, lineHeight: '22px', display: 'flex', alignItems: 'center' }}>\n {t('row.title')}\n <HelpIcon label={t('row.helpLabel')} help={t('row.help')} />\n </div>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.description')}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>\n {themes.map((flavor) => {\n const selected = choice === flavor.id\n const subtitle = subtitleText(flavor.id, t)\n return (\n <button\n key={flavor.id}\n type=\"button\"\n aria-pressed={selected}\n onClick={() => void select(flavor.id)}\n style={{\n ...(selected ? buttonActive : buttonBase),\n flexDirection: subtitle !== null ? 'column' : 'row',\n alignItems: subtitle !== null ? 'flex-start' : 'center',\n gap: subtitle !== null ? 2 : 6,\n padding: subtitle !== null ? '5px 12px' : '6px 12px',\n }}\n >\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n <span aria-hidden=\"true\" style={{ width: 12, height: 12, borderRadius: 3, background: flavor.accent, flex: 'none' }} />\n {flavor.label}\n </span>\n {subtitle !== null && (\n <span style={{ fontSize: 10, lineHeight: '14px', color: 'var(--dsw-alias-label-tertiary)' }}>\n {subtitle}\n </span>\n )}\n </button>\n )\n })}\n <button\n key=\"off\"\n type=\"button\"\n aria-pressed={choice === 'off'}\n onClick={() => void select('off')}\n style={choice === 'off' ? buttonActive : buttonBase}\n >\n {t('row.off')}\n </button>\n </div>\n\n {/* Shiki style pick (item M). */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.shikiStyle')}\n </span>\n <Segmented\n label={t('row.shikiStyle')}\n value={style}\n options={[\n { id: 'default' as const, label: t('row.shikiDefault') },\n { id: 'italic-comments' as const, label: t('row.shikiItalicComments') },\n ]}\n onSelect={setShikiStyle}\n />\n </div>\n\n {/* Power-user token overrides (item K). */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n <button\n type=\"button\"\n aria-expanded={overridesOpen}\n onClick={() => { setOverridesOpen(!overridesOpen) }}\n style={{ ...buttonBase, alignSelf: 'flex-start', fontSize: 12, padding: '4px 10px' }}\n >\n {overridesOpen ? `▾` : `▸`} {t('row.overrides')} ({Object.keys(overrideMap).length})\n </button>\n {overridesOpen && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.overridesHint')}\n </div>\n {Object.keys(overrideMap).length === 0 && draftRows.length === 0 && (\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('row.overridesEmpty')}\n </div>\n )}\n {Object.entries(overrideMap).map(([key, value]) => (\n <div key={key} style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignItems: 'center' }}>\n <input\n type=\"text\"\n aria-label={t('row.overridesKey')}\n defaultValue={key}\n onBlur={(e) => { commitPersistedKey(key, e.target.value) }}\n placeholder=\"--dsw-static-blue-500\"\n style={{ flex: '1 1 220px', ...inputBase }}\n />\n <input\n type=\"text\"\n aria-label={t('row.overridesValue')}\n defaultValue={value}\n onBlur={(e) => { commitPersistedValue(key, e.target.value) }}\n placeholder=\"#89b4fa\"\n style={{ flex: '1 1 140px', ...inputBase }}\n />\n <button\n type=\"button\"\n aria-label={t('row.overridesRemove')}\n onClick={() => { removePersisted(key) }}\n style={{ ...buttonBase, padding: '4px 8px', fontSize: 12 }}\n >\n ✕\n </button>\n </div>\n ))}\n {draftRows.map((row, index) => (\n <div key={row.id} style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignItems: 'center' }}>\n <input\n type=\"text\"\n aria-label={t('row.overridesKey')}\n defaultValue={row.key}\n onBlur={(e) => { commitDraftKey(index, e.target.value) }}\n placeholder=\"--dsw-static-blue-500\"\n style={{ flex: '1 1 220px', ...inputBase }}\n />\n <input\n type=\"text\"\n aria-label={t('row.overridesValue')}\n defaultValue={row.value}\n onBlur={(e) => { commitDraftValue(index, e.target.value) }}\n placeholder=\"#89b4fa\"\n style={{ flex: '1 1 140px', ...inputBase }}\n />\n <button\n type=\"button\"\n aria-label={t('row.overridesRemove')}\n onClick={() => { setDraftRows(draftRows.filter((_, i) => i !== index)) }}\n style={{ ...buttonBase, padding: '4px 8px', fontSize: 12 }}\n >\n ✕\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n onClick={() => {\n nextDraftId.current += 1\n setDraftRows([...draftRows, { id: nextDraftId.current, key: '', value: '' }])\n }}\n style={{ ...buttonBase, alignSelf: 'flex-start', fontSize: 12, padding: '4px 10px' }}\n >\n + {t('row.overridesAdd')}\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}","/**\n * Runtime seam stamper for the Catppuccin glass layer.\n *\n * The glass stylesheet keys off stable data-* hooks (`data-dsh-glass-frame`,\n * `data-dsh-glass-trajectory`, `data-dsh-glass-stats`, …) that are NOT part\n * of the stock DSH markup, so this module stamps them onto the matching\n * elements at runtime — the stylesheet works with zero base edits. Each\n * selector uses only stable attributes already present in the stock UI\n * (`data-composer-card`, `data-conversation-composer-overlay`, `data-slot`,\n * ARIA roles) or lightningcss-preserved class-name substrings.\n *\n * Stamps are idempotent and inert without the `data-dsh-glass` root attribute\n * (the whole stylesheet is gated on it), so they are simply left in place when\n * the layer flips off — \"off\" still renders the exact stock UI.\n */\n\ninterface Seam {\n /** Attribute to stamp (bare name; value is always ''). */\n readonly attribute: string\n /** CSS selector for the element(s) to stamp. */\n readonly selector: string\n /** Stamp only the first (topmost) match, not every descendant match. */\n readonly first?: boolean\n}\n\nconst SEAMS: readonly Seam[] = [\n // The layout frame: the sidebar column's direct parent.\n { attribute: 'data-dsh-glass-frame', selector: ':has(> [class*=\"sidebarCol\"])' },\n // The sidebar content root (topmost `root` under the column — settings\n // internals also carry a `root` class but sit deeper, so first match wins).\n { attribute: 'data-dsh-glass-sidebar-root', selector: '[class*=\"sidebarCol\"] [class*=\"root\"]', first: true },\n // New-session button (a raised-surface seam).\n { attribute: 'data-dsh-glass-surface', selector: 'button[class*=\"newSession\"]' },\n // Trajectory view (the composer-overlay view).\n { attribute: 'data-dsh-glass-trajectory', selector: '[data-conversation-composer-overlay]' },\n // Right panel (会话右侧栏 / 详情栏). The column was renamed upstream —\n // `detailsCol` through 0.1.2-rc.1, `rightbarCol` from 0.1.5-rc.2 on\n // (ui-layout/src/client/AppFrame.module.css) — and the old `[class*=\"root\"]`\n // descendant had no stable target: ui-sidebar-right ships `.session` /\n // `.panel`, while the tab views it hosts DO carry a `root` class\n // (ui-sidebar-files / browser / terminal), so the stamp landed on whichever\n // content view happened to be open — and on none of them for the document\n // preview. The panel itself carries the stable `data-sidebar-right-panel`\n // attribute (SidebarRight.tsx), which is what the stylesheet actually wants\n // (it makes the panel background transparent so the ground shows through).\n { attribute: 'data-dsh-glass-details', selector: '[class*=\"rightbarCol\"] [data-sidebar-right-panel], [class*=\"detailsCol\"] [class*=\"root\"]', first: true },\n // Composer bar root: the composer card's direct parent.\n { attribute: 'data-dsh-glass-inputbar', selector: ':has(> [data-composer-card])' },\n // Composer attach \"+\" button (ui-conversation InputBar.tsx -> css.add).\n { attribute: 'data-dsh-glass-add', selector: '[data-composer-card] [class*=\"add\"]' },\n // Session stats line under the composer (composer.dock slot). The slot renders\n // the entry with no wrapper of its own, so StatsPills' own root is both the\n // slot's direct child and a `root`-classed div (`<div className={css.root}\n // data-composer-stats>` in ui-chat/src/client/chat/StatsPills.tsx, present in\n // 0.1.5-rc.2 and 0.1.7 alike). Picking the row by position (`> *`) keeps\n // working if that class name ever changes; both parts resolve to the same\n // element today, and stamping is idempotent.\n { attribute: 'data-dsh-glass-stats', selector: '[data-slot=\"conversation.composer.dock\"] > *, [data-slot=\"conversation.composer.dock\"] [class*=\"root\"]' },\n // Settings dialog: a fixed overlay portalled inside the sidebar column\n // (the wrapper around the dialog panel in dsh-client-ui-settings-general).\n // Its rows/pickers paint themselves with the opaque raised-surface tokens,\n // so the stylesheet needs one hook on the dialog to re-point them at glass\n // mixes. Matched by the panel's accessible attributes, not its CSS-module\n // class: the host class name is a build hash (`VOzbGW_overlay`) that changes\n // whenever the host stylesheet does, and a stale selector would silently\n // drop the settings dialog back to opaque cards.\n { attribute: 'data-dsh-glass-settings', selector: ':has(> [role=\"dialog\"][aria-modal=\"true\"])' },\n]\n\nfunction stamp(seam: Seam): void {\n if (seam.first) {\n const el = document.querySelector(seam.selector)\n if (el !== null && !el.hasAttribute(seam.attribute)) el.setAttribute(seam.attribute, '')\n return\n }\n for (const el of document.querySelectorAll(seam.selector)) {\n if (!el.hasAttribute(seam.attribute)) el.setAttribute(seam.attribute, '')\n }\n}\n\nfunction stampAll(): void {\n for (const seam of SEAMS) stamp(seam)\n}\n\n/**\n * Stamp the seams once, then keep them stamped as React remounts nodes.\n *\n * The observer callback is debounced through `requestAnimationFrame` (item\n * N): DSH chat streaming mutates the DOM per token, and re-stamping on\n * every single mutation would re-run every selector per token. One frame\n * merges all mutations into one `stampAll()` — a streamed burst of N\n * mutations costs 1 stamp pass, and a frame with no mutations costs\n * nothing (the dirty flag skips the no-op stamp). Stamping stays idempotent\n * and cheap: `stamp()` only sets attributes that are missing.\n *\n * @returns a disposer that disconnects the observer and cancels any\n * pending frame.\n */\nexport function startGlassSeamStamper(): () => void {\n stampAll()\n let frame: number | undefined\n let dirty = false\n let disposed = false\n const stampFrame = (): void => {\n frame = undefined\n if (!dirty) return\n dirty = false\n stampAll()\n }\n const schedule = (): void => {\n // A MutationObserver callback can already be queued as a microtask when the\n // disposer runs — disconnect() does not recall it. Without this guard that\n // callback re-arms a frame and stamps *after* dispose (full-suite timing\n // exposes it; single-file runs usually win the race).\n if (disposed) return\n dirty = true\n if (frame !== undefined) return\n frame = requestAnimationFrame(stampFrame)\n }\n const observer = new MutationObserver(schedule)\n observer.observe(document.documentElement, { childList: true, subtree: true })\n return () => {\n disposed = true\n observer.disconnect()\n if (frame !== undefined) cancelAnimationFrame(frame)\n frame = undefined\n dirty = false\n }\n}\n","/**\n * AUTO-GENERATED by scripts/gen-glass-css.mjs — do not edit by hand.\n * The glass stylesheet text, generated from\n * src/client/glass/glass.module.css on every build. The browser half\n * mounts this text as a <style> tag only while the glass layer is on\n * (item II — lazy CSS), so editing the stylesheet means editing\n * glass.module.css and rebuilding.\n */\nexport const GLASS_CSS_TEXT: string = \"[data-dsh-glass] body{--dsh-glass-card:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(52% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-card-raised:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(64% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-card-hover:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(76% * var(--dsh-glass-frost,1)), transparent);--dsh-glass-rim:color-mix(in srgb, var(--dsw-alias-label-primary) 18%, transparent);--dsh-glass-rim-soft:color-mix(in srgb, var(--dsw-alias-label-primary) 12%, transparent);--dsh-glass-rim-strong:color-mix(in srgb, var(--dsw-alias-label-primary) 30%, transparent);--dsh-glass-edge:inset 0 1px 0 #ffffff6b;--dsh-glass-drop:0 10px 32px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 38%, transparent);--dsh-glass-input-shadow:0 1px 2px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 65%, transparent), 0 8px 24px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 80%, transparent)}[data-dsh-glass] body[data-ds-dark-theme]{--dsh-glass-rim:color-mix(in srgb, var(--dsw-alias-label-primary) 24%, transparent);--dsh-glass-rim-soft:color-mix(in srgb, var(--dsw-alias-label-primary) 16%, transparent);--dsh-glass-rim-strong:color-mix(in srgb, var(--dsw-alias-label-primary) 30%, transparent);--dsh-glass-edge:inset 0 1px 0 #ffffff14;--dsh-glass-drop:0 10px 32px #02060e73;--dsh-glass-input-shadow:0 1px 2px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 65%, transparent), 0 8px 24px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 80%, transparent)}[data-dsh-glass] body{background:color-mix(in srgb, color-mix(in srgb, var(--dsw-alias-bg-base), #fff calc(var(--dsh-glass-brightness-white,0) * 100%)), #000 calc(var(--dsh-glass-brightness-black,0) * 100%))}[data-dsh-glass] [data-dsh-glass-frame],[data-dsh-glass] [data-phase],[data-dsh-glass] [data-dsh-glass-details]{background:0 0}[data-dsh-glass-float] [data-phase=active] header{z-index:8;position:relative}[data-dsh-glass-float] [class*=banner]{position:static}[data-dsh-glass-float] [data-phase=active] [data-conversation-scroll]{margin-top:-95px;padding-top:107px}[data-dsh-glass] [data-phase] [class*=composerSeat][class*=composerSeat]{background:0 0}[data-dsh-glass] [data-dsh-glass-fade]{z-index:7;pointer-events:none;backdrop-filter:blur(5px);background:#ffffff2e;height:13px;position:fixed;left:0;right:0}[data-dsh-glass] body[data-ds-dark-theme] [data-dsh-glass-fade]{background:#00000024}[data-dsh-glass] [data-dsh-glass-fade=top]{top:0;-webkit-mask-image:linear-gradient(#000 0%,#0000 100%);mask-image:linear-gradient(#000 0%,#0000 100%)}[data-dsh-glass][data-windows-titlebar] [data-dsh-glass-fade=top]{display:none}[data-dsh-glass] [data-dsh-glass-fade=bottom]{bottom:0;-webkit-mask-image:linear-gradient(#0000 0%,#000 100%);mask-image:linear-gradient(#0000 0%,#000 100%)}[data-dsh-glass-float] [data-menu-material=translucent],[data-dsh-glass-float] [role=menu]:not([data-menu-material]):not([data-menu-material] *),[data-dsh-glass-float] [role=dialog],[data-dsh-glass-float] [role=alert],[data-dsh-glass-float] [data-trigger-menu],[data-dsh-glass-float] [data-dsh-glass-surface]{border-radius:14px}[data-dsh-glass-float] [role=menuitem],[data-dsh-glass-float] [role=tooltip],[data-dsh-glass-float] [class*=pill]{border-radius:8px}[data-dsh-glass-float] button[class*=button]{border-radius:10px}[data-dsh-glass-float] [class*=iconButton],[data-dsh-glass-float] [class*=searchButton]{border-radius:8px}[data-dsh-glass-float] [class*=block]{--dsl-code-block-border-radius:14px;--dsl-diff-radius:14px;--dsl-read-radius:14px;--dsl-terminal-radius:14px;--dsl-web-radius:14px;--dsl-search-radius:14px;border-radius:14px}[data-dsh-glass-float] [data-dsh-glass-add]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-add]:hover:not(:disabled){background:var(--dsh-glass-card-hover)}[data-dsh-glass-float] [data-dsh-glass-surface]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-surface]:hover:not(:disabled){background:var(--dsh-glass-card-hover)}[data-dsh-glass-float] [data-conversation-scroll] [class*=bubble]{border:1px solid var(--dsh-glass-rim-soft);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(46% * var(--dsh-glass-frost,1)), transparent);border-radius:14px}[data-dsh-glass-float] [class*=card]{border-radius:14px}[data-dsh-glass] [data-dsh-glass-settings]{--dsh-glass-settings-raised:calc(38% + 38% * var(--dsh-glass-frost,1));--dsh-glass-settings-soft:calc(30% + 30% * var(--dsh-glass-frost,1));--dsw-alias-bg-module-platform:color-mix(in srgb, var(--dsw-static-neutral-bluish-800) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-3:color-mix(in srgb, var(--dsw-static-neutral-bluish-800) var(--dsh-glass-settings-soft), transparent);--dsw-alias-bg-layer-2:color-mix(in srgb, var(--dsw-static-neutral-bluish-850) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-1:color-mix(in srgb, var(--dsw-static-neutral-bluish-850) var(--dsh-glass-settings-soft), transparent);--dsw-specific-sidebar-nav-item-active:color-mix(in srgb, var(--dsw-static-neutral-bluish-750) var(--dsh-glass-settings-raised), transparent);--dsw-specific-sidebar-nav-item-hover:color-mix(in srgb, var(--dsw-static-neutral-bluish-850) var(--dsh-glass-settings-soft), transparent)}[data-dsh-glass] body:not([data-ds-dark-theme]) [data-dsh-glass-settings]{--dsw-alias-bg-module-platform:color-mix(in srgb, var(--dsw-static-neutral-bluish-60) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-3:color-mix(in srgb, var(--dsw-static-neutral-bluish-00) var(--dsh-glass-settings-soft), transparent);--dsw-alias-bg-layer-2:color-mix(in srgb, var(--dsw-static-neutral-bluish-00) var(--dsh-glass-settings-raised), transparent);--dsw-alias-bg-layer-1:color-mix(in srgb, var(--dsw-static-neutral-bluish-00) var(--dsh-glass-settings-soft), transparent);--dsw-specific-sidebar-nav-item-active:color-mix(in srgb, var(--dsw-static-neutral-bluish-100) var(--dsh-glass-settings-raised), transparent);--dsw-specific-sidebar-nav-item-hover:color-mix(in srgb, var(--dsw-static-neutral-bluish-75) var(--dsh-glass-settings-soft), transparent)}[data-dsh-glass-float] [data-phase] header{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:20px;margin:12px 16px 0;padding:10px 16px 8px}[data-dsh-glass-float] [data-phase] header:after{display:none}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] [data-phase] header{margin-left:28px}[data-dsh-glass-float] [class*=sidebarCol]{--dsw-specific-sidebar-fill:transparent;z-index:9;border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-drop);border-radius:20px;margin:12px;padding:10px 12px 14px;position:relative;overflow:hidden}[data-dsh-glass-float] [class*=sidebarCol]:before{content:\\\"\\\";border-radius:inherit;background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge);z-index:-1;pointer-events:none;transition:border-radius .15s var(--ds-ease-in-out);position:absolute;inset:0}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] [class*=sidebarCol]{transition:margin .15s var(--ds-ease-in-out), border-radius .15s var(--ds-ease-in-out);border-radius:16px;margin:12px -12px 12px 12px;padding:0}[data-dsh-glass-float] [data-dsh-glass-frame]:not([data-sidebar-collapsed]) [data-dsh-glass-sidebar-root]{width:100%!important}[data-dsh-glass-float] [data-dsh-glass-trajectory]{border:1px solid var(--dsh-glass-rim);background:var(--dsh-glass-card);width:calc(100% - 32px);height:calc(100% - 20px);box-shadow:var(--dsh-glass-edge), var(--dsh-glass-drop);border-radius:20px;margin:8px 16px 12px;overflow:hidden}[data-dsh-glass-float] [data-dsh-glass-trajectory] [role=toolbar],[data-dsh-glass-float] [data-dsh-glass-trajectory] section[aria-label=Trajectory\\\\ timeline]{background:0 0}[data-dsh-glass-float] [data-composer-card],[data-dsh-glass-float] [data-composer-card]:after{border-radius:24px}[data-dsh-glass-float] [data-composer-card]{z-index:8;isolation:isolate;border:1px solid var(--dsh-glass-rim-strong);box-shadow:var(--dsh-glass-input-shadow);background:0 0;position:relative}[data-dsh-glass-float] [data-composer-card]:before{content:\\\"\\\";z-index:-1;border-radius:inherit;background:var(--dsh-glass-card);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px));pointer-events:none;position:absolute;inset:0}[data-dsh-glass-float] [data-dsh-glass-inputbar]:not([class*=hero]):not(:has([data-dsh-glass-stats])){padding-bottom:12px}[data-dsh-glass-float] [role=treeitem][aria-selected=true]{background:var(--dsw-alias-interactive-bg-hover)}[data-dsh-glass-float] button[class*=button]:hover:not(:disabled),[data-dsh-glass-float] [role=menuitem]:hover:not(:disabled){box-shadow:0 0 12px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 20%, transparent)}[data-dsh-glass-float] [data-menu-material=translucent]:not(:focus-visible){--dsw-menu-surface-fill:var(--dsh-glass-card-raised);--dsw-menu-backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [role=menu]:not([data-menu-material]):not([data-menu-material] *){background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim-soft);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-menu-material=translucent]:has([role=group]>[role=menuitemradio]){--dsw-menu-surface-fill:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 70%, transparent)}[data-dsh-glass-float] [data-menu-group]:has(>[role=menuitemradio])>[data-menu-group-heading]{background:var(--dsh-glass-card-raised);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:999px;align-items:center;width:fit-content;margin:3px 0 5px 6px;padding:3px 10px;display:inline-flex}[data-dsh-glass-float] [role=dialog][aria-modal=true]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);box-shadow:var(--dsh-glass-edge);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass] [data-conversation-scroll]{text-shadow:0 0 1px #ffffff80}[data-dsh-glass] body[data-ds-dark-theme] [data-conversation-scroll]{text-shadow:0 0 1px #0006}[data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot]{color:var(--dsw-alias-label-secondary)}[data-dsh-glass]{--dsh-glass-entry-scale:1}[data-dsh-glass-compat]{--dsh-glass-entry-scale:0}[data-dsh-glass] [data-phase=hero]{animation:dsh-glass-in calc(.32s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}[data-dsh-glass] [data-phase=active]{animation:dsh-glass-in calc(.3s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}[data-dsh-glass] [data-testid^=view-]{animation:dsh-glass-in calc(.26s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}[data-dsh-glass] [data-tool]{animation:dsh-glass-rise calc(.3s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out) both}[data-dsh-glass] [role=dialog]{animation:dsh-glass-dialog-in calc(.24s * var(--dsh-glass-entry-scale,1)) var(--ds-ease-in-out)}@keyframes dsh-glass-in{0%{opacity:0}}@keyframes dsh-glass-rise{0%{opacity:0;transform:translateY(6px)}}@keyframes dsh-glass-dialog-in{0%{opacity:0;transform:translateY(8px)scale(.985)}}[data-dsh-glass] :focus-visible{outline:2px solid color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 85%, transparent);outline-offset:1px}[data-dsh-glass] ::selection{background:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 35%, transparent)}[data-dsh-glass-compat] [role=menu]:not([data-menu-material]):not([data-menu-material] *),[data-dsh-glass-compat] [class*=popover],[data-dsh-glass-compat] [class*=dropdown]{backdrop-filter:blur(12px)}[data-dsh-glass-compat] [data-menu-material=translucent]:not(:focus-visible){--dsw-menu-surface-fill:var(--dsh-glass-card-raised);--dsw-menu-backdrop-filter:blur(12px)}[data-dsh-glass-compat] [data-sidebar-right-panel][data-sidebar-right-open],[data-dsh-glass-compat] [data-sidebar-right-panel][data-sidebar-right-open] [class*=panel]{backdrop-filter:blur(12px)}[data-dsh-glass-compat] [role=menu]:not([data-menu-material]):not([data-menu-material] *),[data-dsh-glass-compat] [class*=popover],[data-dsh-glass-compat] [class*=dropdown]{background:var(--dsh-glass-card-raised)}[data-dsh-glass-compat] [data-composer-card]{isolation:isolate;backdrop-filter:none;background:0 0;position:relative}[data-dsh-glass-compat] [data-composer-card]:before{content:\\\"\\\";z-index:-1;border-radius:inherit;background:var(--dsh-glass-card-raised);backdrop-filter:blur(12px);pointer-events:none;position:absolute;inset:0}[data-dsh-glass-compat] [role=menu]:not([data-menu-material]):not([data-menu-material] *):not(:focus-visible),[data-dsh-glass-compat] [data-composer-card]:not(:focus-visible),[data-dsh-glass-compat] [class*=popover]:not(:focus-visible),[data-dsh-glass-compat] [class*=dropdown]:not(:focus-visible){outline:1px solid var(--dsh-glass-rim);outline-offset:-1px}[data-dsh-glass-compat] [role=dialog][aria-modal=true]{background:var(--dsh-glass-card-raised);border:1px solid var(--dsh-glass-rim);backdrop-filter:blur(var(--dsh-glass-blur,12px))}@media (prefers-reduced-motion:reduce){[data-dsh-glass] [data-phase=hero],[data-dsh-glass] [data-phase=active],[data-dsh-glass] [data-testid^=view-],[data-dsh-glass] [data-tool],[data-dsh-glass] [role=dialog]{animation:none}}\"\n","/**\n * Durable Catppuccin state — the shared contract between the two halves.\n *\n * Why this exists: localStorage is scoped per origin, so it is the wrong place\n * for the ONLY copy of a preference. It is per-browser (two browsers on one\n * machine disagree), per-loopback-port (a second Desktop instance that lands\n * on the next free port gets a different origin — the official shell pins\n * `19387` and `anywhere-labs/dsh-desktop` starts at `43120` and increments on\n * a bind collision, both observed 2026-09-24), and it disappears whenever the\n * user clears site data. The durable copy lives in the official settings seam\n * under the DSH home, which is the machine-wide truth every browser and every\n * profile entry reads.\n *\n * (Historical note, corrected 2026-09-24: the 0.5.0 rationale claimed DSH\n * Desktop launched the profile with `--port 0`, \"a fresh random port every\n * launch\". That was already untrue when 0.5.0 shipped — the community shell\n * pinned a stable port on 2026-08-21, and the official shell passes an\n * explicit `--port 19387`. The design is unchanged and still justified by the\n * reasons above, but do not repeat the port-per-launch claim.)\n *\n * Since 0.5.0 the DURABLE copy lives in the official settings seam, which\n * persists under the DSH home exactly like the legacy\n * `$DSH_HOME/catppuccin-state.json` did — origin-independent, so it survives\n * the Desktop's per-launch port churn. The legacy file is kept as a\n * read-only migration source (`src/legacy-state.ts`) and rolled into the\n * settings document once (`src/index.ts`). Browser localStorage remains the\n * in-browser cache and cross-tab sync bus, and the Client's fallback when the\n * settings transport is unavailable. This module is dependency-free so both\n * bundles inline it (like `update-check.ts`).\n *\n * The seam itself is version-dependent (issue #15): DSH <= 0.1.6-alpha.2\n * serves a Client `ctx.settingsScope` bound to a namespace the plugin\n * registers itself (`CATPPUCCIN_SETTINGS_NS`), while >= 0.1.7-alpha.1 serves\n * `ctx.configForms` projecting the plugin's volatile `Config` form, keyed by\n * the PROFILE ENTRY ID (`CATPPUCCIN_ENTRY_ID`). Both are addressed from this\n * one contract (see `src/client/state-sync.ts`).\n */\nexport const STATE_VERSION = 1\n\n/** Release channels the update check knows about (a persisted preference;\n * `selectNewest` in `update-check.ts` consumes it). */\nexport type UpdateChannel = 'latest' | 'beta'\n\n/** Shiki syntax-highlighting style variants (see `src/client/shiki-tokens.ts`). */\nexport type ShikiStyle = 'default' | 'italic-comments'\n\n/** Legacy settings namespace (DSH <= 0.1.6-alpha.2): the Host registers it\n * through `settings.installSection`, the Client binds it through\n * `ctx.settingsScope` (see `src/settings-catppuccin.ts`). */\nexport const CATPPUCCIN_SETTINGS_NS = 'catppuccin'\n\n/**\n * Profile entry id carrying the plugin (DSH >= 0.1.7-alpha.1): the settings\n * service projects our volatile `Config` into a form named by the ACTIVE\n * PROFILE ENTRY's id, so this constant is the new seam's namespace.\n *\n * It is a CONTRACT with `cordis.patch.yml`: the `insert` row whose `name` is\n * `@nonamelego/dsh-catppuccin` must keep `id: dsh-catppuccin`, because the\n * Client can only address the form by that id (asserted by\n * `tests/settings-seam.spec.ts`). A user who renames the entry loses the new\n * seam and degrades to localStorage-only — the legacy seam is unaffected,\n * since that namespace is registered by the plugin itself.\n */\nexport const CATPPUCCIN_ENTRY_ID = 'dsh-catppuccin'\n\n/** State file name under the DSH home (kept next to the Desktop-managed\n * `cordis.patch.yml` so it survives the Desktop's per-launch port churn). */\nexport const STATE_FILENAME = 'catppuccin-state.json'\n\n/**\n * Whether a raw settings view carries a user layer at all.\n *\n * The two seams answer this differently and the difference is load-bearing\n * (issue #15): the NEW form's `user` is the profile patch's `override`, which\n * `configEditor.configuration()` defaults to `{}` — so \"absent\" arrives as an\n * EMPTY OBJECT, and `!== undefined` would be true forever. The LEGACY\n * document omits the field entirely when the document holds no such section,\n * so the old `!== undefined` test stays correct there. Callers must use the\n * predicate their channel defines (see `src/client/state-sync.ts`).\n * @param user - a snapshot's raw user layer.\n * @returns whether it holds at least one entry.\n */\nexport function hasUserLayerSection(user: unknown): boolean {\n return typeof user === 'object' && user !== null && !Array.isArray(user) && Object.keys(user).length > 0\n}\n\n/** The four registered Catppuccin theme ids. MUST stay in sync with the\n * `themeId` of `CATPPUCCIN_FLAVORS` in `src/client/palettes.ts` — guarded by\n * `tests/state.spec.ts` — because the persisted flavour value IS the theme id. */\nexport const CATPPUCCIN_THEME_IDS = [\n 'catppuccin-latte',\n 'catppuccin-frappe',\n 'catppuccin-macchiato',\n 'catppuccin-mocha',\n] as const\n\n/** A persisted flavour choice: one registered theme id or `off` (fall back to\n * the official theme). */\nexport type FlavorValue = (typeof CATPPUCCIN_THEME_IDS)[number] | 'off'\n\n/** Durable glass-layer settings (no derived `dark` field — that resolves at\n * runtime from the active theme). */\nexport interface GlassState {\n /** Layer enable flag. */\n enabled: boolean\n /** Rendering mode. */\n mode: 'mica' | 'compat'\n /** Glass blur radius, px (0-40). */\n blur: number\n /** Glass fill frost, 0-100. */\n frost: number\n /** Backdrop brightness, 0-100. */\n brightness: number\n}\n\n/** The whole durable state the plugin persists. */\nexport interface CatppuccinState {\n /** Schema version; anything else is treated as unknown and defaulted. */\n version: typeof STATE_VERSION\n /** Selected flavour (theme id or `off`). */\n flavor: FlavorValue\n /** Glass-layer settings (enable flag + knobs). */\n glass: GlassState\n /** Automatically re-check for updates (boot + periodic, while on). */\n autoCheck: boolean\n /** Release channel the update check chases. */\n updateChannel: UpdateChannel\n /** Per-token `--dsw-*` overrides merged LAST into the active theme. */\n overrides: Record<string, string>\n /** Shiki syntax-highlighting style variant. */\n shikiStyle: ShikiStyle\n}\n\n/** The settings-document section: `CatppuccinState` minus the synthetic\n * `version` field — the official seam resolves defaults, composition and the\n * user layer itself, so no plugin-side version is stored. */\nexport interface CatppuccinSettingsSection {\n /** Selected flavour (theme id or `off`). */\n flavor: FlavorValue\n /** Glass-layer settings (enable flag + knobs). */\n glass: GlassState\n /** Automatically re-check for updates (boot + periodic, while on). */\n autoCheck: boolean\n /** Release channel the update check chases. */\n updateChannel: UpdateChannel\n /** Per-token `--dsw-*` overrides merged LAST into the active theme. */\n overrides: Record<string, string>\n /** Shiki syntax-highlighting style variant. */\n shikiStyle: ShikiStyle\n}\n\n/** Shipped glass defaults — the single source of truth; the client glass layer\n * (`src/client/glass/glass-layer.ts`) derives its knob defaults from here. */\nexport const DEFAULT_GLASS: GlassState = {\n enabled: false,\n mode: 'mica',\n blur: 5,\n frost: 20,\n brightness: 50,\n}\n\n/** Shipped update-check preference: automatic checks on. */\nexport const DEFAULT_AUTO_CHECK = true\n/** Shipped update-check channel: chase the stable `latest` tag. */\nexport const DEFAULT_UPDATE_CHANNEL: UpdateChannel = 'latest'\n/** Shipped syntax-highlighting style. */\nexport const DEFAULT_SHIKI_STYLE: ShikiStyle = 'default'\n\n/** A fully default state: no Catppuccin flavour and no glass. */\nexport function defaultState(): CatppuccinState {\n return {\n version: STATE_VERSION,\n flavor: 'off',\n glass: { ...DEFAULT_GLASS },\n autoCheck: DEFAULT_AUTO_CHECK,\n updateChannel: DEFAULT_UPDATE_CHANNEL,\n overrides: {},\n shikiStyle: DEFAULT_SHIKI_STYLE,\n }\n}\n\n/**\n * Keep only well-formed custom token overrides: string values under a `--`\n * key (the token shape `--dsw-*` names). Everything else is dropped so a\n * hand-edited document can never smuggle junk into the theme registration.\n */\nexport function sanitizeOverrides(input: unknown): Record<string, string> {\n const out: Record<string, string> = {}\n if (typeof input !== 'object' || input === null) return out\n for (const [key, value] of Object.entries(input)) {\n if (typeof value === 'string' && key.startsWith('--')) out[key] = value\n }\n return out\n}\n\n/**\n * Whether a raw overrides map carries entries {@link sanitizeOverrides} would\n * drop — a key that is not a `--` token, or a non-string value.\n *\n * The settings-document schema types `overrides` as a dict of strings only, so\n * a hand-edited document can hold such entries. The client reads them away but\n * never wrote the cleaned map back, so every settings publish re-ran the\n * \"document wins\" adoption for a difference nothing could clear (audit F7).\n * The caller uses this to push the sanitized shape back once, so the document\n * converges instead of drifting forever.\n */\nexport function hasUnpersistableOverrides(raw: unknown): boolean {\n if (typeof raw !== 'object' || raw === null) return false\n return Object.entries(raw).some(([key, value]) => typeof value !== 'string' || !key.startsWith('--'))\n}\n\n/** Clamp a finite number into [min, max]; non-finite values fall back. */\nfunction clampFinite(value: unknown, min: number, max: number, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value)\n ? Math.min(max, Math.max(min, value))\n : fallback\n}\n\n/**\n * Normalize arbitrary input (JSON from disk or the wire) into a valid state:\n * unknown/missing fields fall back to defaults, out-of-range numbers clamp,\n * and unknown flavours/invalid enums fall back too. The Host applies this on\n * both read and write so a corrupt file or a hand-crafted payload can never\n * poison the plugin's settings.\n */\nexport function sanitizeState(input: unknown): CatppuccinState {\n const state = defaultState()\n if (typeof input !== 'object' || input === null) return state\n const raw = input as Record<string, unknown>\n\n const flavor = raw.flavor\n if (typeof flavor === 'string' && (CATPPUCCIN_THEME_IDS as readonly string[]).includes(flavor)) {\n state.flavor = flavor as FlavorValue\n } else if (flavor === 'off') {\n state.flavor = 'off'\n }\n\n const glass = typeof raw.glass === 'object' && raw.glass !== null\n ? raw.glass as Record<string, unknown>\n : {}\n state.glass.enabled = glass.enabled === true\n state.glass.mode = glass.mode === 'compat' ? 'compat' : 'mica'\n state.glass.blur = clampFinite(glass.blur, 0, 40, DEFAULT_GLASS.blur)\n state.glass.frost = clampFinite(glass.frost, 0, 100, DEFAULT_GLASS.frost)\n state.glass.brightness = clampFinite(glass.brightness, 0, 100, DEFAULT_GLASS.brightness)\n\n // Preference fields: absent values keep their shipped defaults, so a v1\n // document (predating them) rolls forward without a migration step.\n state.autoCheck = raw.autoCheck !== false\n state.updateChannel = raw.updateChannel === 'beta' ? 'beta' : 'latest'\n state.overrides = sanitizeOverrides(raw.overrides)\n state.shikiStyle = raw.shikiStyle === 'italic-comments' ? 'italic-comments' : 'default'\n\n return state\n}\n\n/**\n * Version-aware migration of an arbitrary persisted document. Version 1\n * documents roll forward through `sanitizeState` (every field added since\n * v1 has a sanitize-time default, so no structural step exists yet); future\n * versions chain their steps here, oldest first. Documents from a NEWER\n * plugin keep every field `sanitizeState` understands instead of being\n * nuked — a downgrade never destroys user state. The version-upgrade\n * convention lives in `docs/state-migrations.md` (item Y).\n */\nexport function migrate(raw: unknown): CatppuccinState {\n if (typeof raw !== 'object' || raw === null) return defaultState()\n const record = raw as Record<string, unknown>\n const version = typeof record.version === 'number' ? record.version : 1\n // Future schema steps chain here, oldest first:\n // let current: unknown = record\n // if (version < 2) current = migrateV1toV2(current)\n // if (version < 3) current = migrateV2toV3(current)\n // (the state contract of each step is spelled out in docs/state-migrations.md)\n return sanitizeState(record)\n}\n\n/** Whether a normalized state carries nothing beyond the shipped defaults —\n * i.e. the user never actually chose anything worth persisting. Used to tell\n * \"no durable state yet\" apart from \"an explicit default choice\". */\nexport function isDefaultState(state: CatppuccinState): boolean {\n const expected = defaultState()\n return state.flavor === expected.flavor\n && state.glass.enabled === expected.glass.enabled\n && state.glass.mode === expected.glass.mode\n && state.glass.blur === expected.glass.blur\n && state.glass.frost === expected.glass.frost\n && state.glass.brightness === expected.glass.brightness\n && state.autoCheck === expected.autoCheck\n && state.updateChannel === expected.updateChannel\n && Object.keys(state.overrides).length === 0\n && state.shikiStyle === expected.shikiStyle\n}\n\n/** Default settings-document section: no flavour and no glass (mirrors\n * `defaultState()` minus the synthetic `version`). */\nexport function defaultSettingsSection(): CatppuccinSettingsSection {\n return {\n flavor: 'off',\n glass: { ...DEFAULT_GLASS },\n autoCheck: DEFAULT_AUTO_CHECK,\n updateChannel: DEFAULT_UPDATE_CHANNEL,\n overrides: {},\n shikiStyle: DEFAULT_SHIKI_STYLE,\n }\n}\n\n/** Drop the synthetic `version` field: full state → settings-document section. */\nexport function settingsSectionFromState(state: CatppuccinState): CatppuccinSettingsSection {\n return {\n flavor: state.flavor,\n glass: { ...state.glass },\n autoCheck: state.autoCheck,\n updateChannel: state.updateChannel,\n overrides: { ...state.overrides },\n shikiStyle: state.shikiStyle,\n }\n}\n\n/** Lift a settings-document section back into the full state-shaped contract\n * (re-sanitized so a hand-edited document can never poison the plugin). */\nexport function stateFromSettingsSection(section: CatppuccinSettingsSection): CatppuccinState {\n return sanitizeState(section)\n}\n\n/** Whether two settings sections are field-for-field equal (used to skip\n * redundant mirror writes and to recognize the Host echoing our own write). */\nexport function settingsSectionsEqual(a: CatppuccinSettingsSection, b: CatppuccinSettingsSection): boolean {\n return a.flavor === b.flavor\n && a.glass.enabled === b.glass.enabled\n && a.glass.mode === b.glass.mode\n && a.glass.blur === b.glass.blur\n && a.glass.frost === b.glass.frost\n && a.glass.brightness === b.glass.brightness\n && a.autoCheck === b.autoCheck\n && a.updateChannel === b.updateChannel\n && a.shikiStyle === b.shikiStyle\n && Object.keys(a.overrides).every((key) => b.overrides[key] === a.overrides[key])\n && Object.keys(b.overrides).every((key) => a.overrides[key] === b.overrides[key])\n}\n","/**\n * Catppuccin glass layer — one toggleable glassmorphism skin over the whole\n * Web surface, riding on top of the Catppuccin themes. Everything the layer\n * owns is an effect: the CSS hooks ride a `data-dsh-glass` attribute on\n * <html> (the stylesheet only applies under it), the seam stamps ride a\n * MutationObserver, and the page-edge fade bands are DOM elements — so\n * switching the flag off (or unloading the plugin) restores the stock UI\n * exactly: no residue, no reload.\n *\n * The page ground is a SOLID colour: the active theme's own `bg-base`\n * token (Latte / Frappé / Macchiato / Mocha), with the brightness knob\n * mixing white/black straight into it. The earlier animated ambient scene\n * (gradient wash + drifting blobs + hue rotation) was removed in favour of\n * this flat ground.\n *\n * The enable flag and every knob persist in localStorage — the in-browser\n * cache and cross-tab sync bus. The DURABLE copy of the same state lives in\n * the official settings store under the DSH home (namespace `catppuccin` / the\n * profile entry form, see `src/state.ts` — the Host declares it, the Client\n * binds whichever seam the host serves through `src/client/state-sync.ts` and\n * hydrates via `applyRemote` / `getRemoteState`):\n * required because localStorage is per-browser and per-origin, while the DSH\n * home is the machine-wide truth (see the rationale in `src/state.ts`). On\n * profiles without a usable settings transport the layer simply keeps working\n * from localStorage alone. The enable flag and knobs themselves stay\n * client-only visual preferences shared with the plugin alone, needing no host\n * configuration.\n */\nimport type { Context } from '@deepseek-ai/cordis'\n// Type-only: pulls the theme plugin's Context merge (ctx.theme + theme/change).\nimport type {} from '@deepseek-ai/dsh-client-ui-theme/client'\nimport { startGlassSeamStamper } from './glass-seams.ts'\nimport { GLASS_CSS_TEXT } from './glass-css.gen.ts'\nimport { DEFAULT_GLASS, type GlassState } from '../../state.ts'\n\n/** html attribute selecting the glass layer: CSS hooks and page effects. */\nexport const GLASS_ATTRIBUTE = 'data-dsh-glass'\n\n/** html attribute selecting the mica (floating-card) layout rules. */\nexport const GLASS_FLOAT_ATTRIBUTE = 'data-dsh-glass-float'\n\n/** html attribute selecting the compatibility (stock-layout) rules. */\nexport const GLASS_COMPAT_ATTRIBUTE = 'data-dsh-glass-compat'\n\n/** localStorage key carrying the layer enable flag. */\nexport const GLASS_ENABLED_KEY = 'dsh.catppuccin.glass.enabled'\n\n/** Plugin identity stamped onto the lazily-mounted glass <style> tag (the\n * shell's unload cleanup keys off `data-plugin`). */\nconst GLASS_STYLE_PLUGIN = '@nonamelego/dsh-catppuccin'\nconst GLASS_STYLE_TAG_ID = 'glass.module.css'\n\n/** The lazily-mounted glass stylesheet <style> tag (undefined while the\n * layer is off — item II: the glass CSS only enters the document while\n * the glass layer is enabled, instead of being injected at plugin load). */\nlet glassStyleTag: HTMLStyleElement | null = null\n\n/** Default state when nothing is stored yet: off (the stock UI stays stock). */\nexport const DEFAULT_ENABLED = DEFAULT_GLASS.enabled\n\n/** Tunable glass knobs. */\nexport interface GlassSettings {\n /** Rendering mode: mica (frosted floating cards) or the stock layout with a generic glass material. */\n mode: 'mica' | 'compat'\n /** Glass backdrop blur radius, px. */\n blur: number\n /** Glass fill opacity, 0-100 (50 = the shipped look; drives the frost multiplier). */\n frost: number\n /** Backdrop brightness, 0-100 (0 = pure black, 50 = transparent, 100 = pure white; half-range per scheme). */\n brightness: number\n}\n\n/** The full state the settings row mirrors (settings + enable flag + scheme). */\nexport interface GlassRowState extends GlassSettings {\n /** Layer enable flag. */\n enabled: boolean\n /** Resolved palette is dark (the brightness knob darkens). */\n dark: boolean\n}\n\n/**\n * Shipped knob defaults — the knob-only view of `DEFAULT_GLASS` in\n * `src/state.ts` (the single source of truth, inlined into both bundles).\n * The shipped look aligns with the reference project\n * (DSH-Transparent-UI-Plugin / Aqua): mica mode, blur 5px, frost 20\n * (the 0-100 slider maps to a 0-1.4 alpha multiplier via frost/50, so 20\n * reads as a light frost) and neutral backdrop brightness.\n */\nexport const SETTINGS_DEFAULTS: GlassSettings = {\n mode: DEFAULT_GLASS.mode,\n blur: DEFAULT_GLASS.blur,\n frost: DEFAULT_GLASS.frost,\n brightness: DEFAULT_GLASS.brightness,\n}\n\n/** Numeric knob keys and their localStorage names. */\nconst NUMERIC_KEYS = {\n blur: 'dsh.catppuccin.glass.blur',\n frost: 'dsh.catppuccin.glass.frost',\n brightness: 'dsh.catppuccin.glass.brightness',\n} as const\ntype NumericKey = keyof typeof NUMERIC_KEYS\n\n/** The localStorage names of the numeric knobs — the reverse of\n * `NUMERIC_KEYS`. Used by the cross-tab `storage` handler: the event's `key`\n * is a localStorage name (`dsh.catppuccin.glass.blur`), so it must be matched\n * against the VALUES, never with `key in NUMERIC_KEYS` (that tests the object's\n * property names — `blur`/`frost`/`brightness` — and is false for every real\n * storage key, which silently killed cross-tab knob sync; audit F1). */\nconst NUMERIC_STORAGE_KEYS: readonly string[] = Object.values(NUMERIC_KEYS)\n\nconst MODE_KEY = 'dsh.catppuccin.glass.mode'\n\n/** Clamp a numeric knob into its sane range. */\nfunction clampSetting(key: NumericKey, value: number): number {\n const max = key === 'blur' ? 40 : 100\n return Number.isFinite(value) ? Math.min(max, Math.max(0, value)) : SETTINGS_DEFAULTS[key]\n}\n\n/** Read one numeric knob from localStorage (absent/parse failure means the default). */\nfunction readSetting(key: NumericKey): number {\n try {\n const raw = localStorage.getItem(NUMERIC_KEYS[key])\n return raw === null ? SETTINGS_DEFAULTS[key] : clampSetting(key, Number(raw))\n } catch {\n return SETTINGS_DEFAULTS[key]\n }\n}\n\n/** Persist one numeric knob (storage failures keep the in-memory state). */\nfunction writeSetting(key: NumericKey, value: number): void {\n try {\n localStorage.setItem(NUMERIC_KEYS[key], String(value))\n } catch {\n /* in-memory state still applies for this tab */\n }\n}\n\n/** Read the rendering mode ('mica' or 'compat'). */\nfunction readMode(): 'mica' | 'compat' {\n try {\n return localStorage.getItem(MODE_KEY) === 'compat' ? 'compat' : 'mica'\n } catch {\n return 'mica'\n }\n}\n\n/** Persist the rendering mode. */\nfunction writeMode(value: 'mica' | 'compat'): void {\n try {\n localStorage.setItem(MODE_KEY, value)\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/** Read the persisted enable flag (absent storage means the default). */\nfunction readEnabled(): boolean {\n try {\n const raw = localStorage.getItem(GLASS_ENABLED_KEY)\n return raw === null ? DEFAULT_ENABLED : raw === 'true'\n } catch {\n return DEFAULT_ENABLED\n }\n}\n\n/** Persist the enable flag (storage failures keep the in-memory state). */\nfunction writeEnabled(value: boolean): void {\n try {\n localStorage.setItem(GLASS_ENABLED_KEY, String(value))\n } catch {\n /* in-memory state still applies for this tab */\n }\n}\n\n/** Resolved scheme from the theme service (falls back to the body attribute). */\nfunction resolveDark(ctx: Context): boolean {\n try {\n return ctx.theme.getTheme().active.colorScheme === 'dark'\n } catch {\n return document.body.hasAttribute('data-ds-dark-theme')\n }\n}\n\n/**\n * The page-edge fade bands injected while enabled (ported from\n * DSH-Transparent-UI-Plugin): two fixed-position, click-through strips\n * that blur the chat content melting into the viewport edges. Both are\n * removed together on disable. The page ground itself is pure CSS (the\n * body rule), so no backdrop element is needed.\n */\nconst FADE_MARKUP = [\n '<span data-dsh-glass-fade=\"top\" aria-hidden=\"true\"></span>',\n '<span data-dsh-glass-fade=\"bottom\" aria-hidden=\"true\"></span>',\n].join('')\n\n/**\n * Owns the glass layer lifecycle: reads the durable enable flag and knobs,\n * and applies / retracts every layer on change. Cross-tab flips arrive through\n * the storage event; the seam observer and every subscription are released\n * when the plugin fiber is disposed.\n */\nexport class GlassLayer {\n private enabled = false\n private settings: GlassSettings = { ...SETTINGS_DEFAULTS }\n /** Cached snapshot for the settings row (stable reference between changes). */\n private snapshot: GlassRowState\n private readonly listeners = new Set<() => void>()\n private dark = false\n private seamDisposer: (() => void) | undefined\n private readonly ctx: Context\n\n /**\n * @param ctx - owning client context (listeners ride this fiber).\n */\n constructor(ctx: Context) {\n this.ctx = ctx\n this.enabled = readEnabled()\n this.reloadSettings()\n this.dark = resolveDark(ctx)\n this.snapshot = this.buildSnapshot()\n\n ctx.effect(() => {\n const onStorage = (event: StorageEvent): void => {\n if (event.key === null) { this.reloadSettings(); this.enabled = readEnabled(); this.sync() }\n else if (event.key === GLASS_ENABLED_KEY) {\n this.enabled = readEnabled()\n this.sync()\n } else if (event.key === MODE_KEY || NUMERIC_STORAGE_KEYS.includes(event.key)) {\n this.reloadSettings()\n if (this.enabled) this.applySettings()\n this.publish()\n }\n }\n window.addEventListener('storage', onStorage)\n // Follow the Appearance switch: the brightness knob's half-range and\n // the mix direction flip with the resolved scheme. Runs even while\n // disabled so the settings row stays correct.\n const themeListener = ctx.on('theme/change', () => {\n this.dark = resolveDark(ctx)\n if (this.enabled) this.applySettings()\n this.publish()\n })\n return () => {\n window.removeEventListener('storage', onStorage)\n themeListener()\n this.unmount()\n }\n }, 'catppuccin: glass layer lifecycle')\n\n // Apply the restored state: mount the layer when the persisted flag is on\n // (the settings row reflects the same snapshot, so the two stay in sync).\n this.sync()\n }\n\n /** Current state snapshot (stable reference until the next change). */\n getSnapshot(): GlassRowState {\n return this.snapshot\n }\n\n /** Subscribe to snapshot changes. Returns the disposer. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n /** The durable subset of the current layer state (no derived `dark`). */\n getRemoteState(): GlassState {\n return {\n enabled: this.enabled,\n mode: this.settings.mode,\n blur: this.settings.blur,\n frost: this.settings.frost,\n brightness: this.settings.brightness,\n }\n }\n\n /** Overlay durable state hydrated from the Host file: persist it to\n * localStorage (the cache), apply it to the live layer, and republish so\n * the settings row reflects the restored choice. */\n applyRemote(remote: GlassState): void {\n this.enabled = remote.enabled\n this.settings = {\n mode: remote.mode === 'compat' ? 'compat' : 'mica',\n blur: clampSetting('blur', remote.blur),\n frost: clampSetting('frost', remote.frost),\n brightness: clampSetting('brightness', remote.brightness),\n }\n writeEnabled(this.enabled)\n writeMode(this.settings.mode)\n writeSetting('blur', this.settings.blur)\n writeSetting('frost', this.settings.frost)\n writeSetting('brightness', this.settings.brightness)\n this.sync()\n }\n\n /** Flip the layer: persist, then apply or retract every owned effect. */\n setEnabled(value: boolean): void {\n if (value === this.enabled) return\n this.enabled = value\n writeEnabled(value)\n this.sync()\n }\n\n /** Set the rendering mode ('mica' or 'compat'). */\n setMode(value: 'mica' | 'compat'): void {\n if (value === this.settings.mode) return\n this.settings.mode = value\n writeMode(value)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Set the glass blur radius (px). */\n setBlur(value: number): void {\n const next = clampSetting('blur', value)\n if (next === this.settings.blur) return\n this.settings.blur = next\n writeSetting('blur', next)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Set the glass frost amount (0-100). */\n setFrost(value: number): void {\n const next = clampSetting('frost', value)\n if (next === this.settings.frost) return\n this.settings.frost = next\n writeSetting('frost', next)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Set the backdrop brightness (0-100: 0 = pure black, 50 = transparent, 100 = pure white). */\n setBrightness(value: number): void {\n const next = clampSetting('brightness', value)\n if (next === this.settings.brightness) return\n this.settings.brightness = next\n writeSetting('brightness', next)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Restore every knob to the shipped defaults (persisted immediately). */\n resetDefaults(): void {\n this.settings = { ...SETTINGS_DEFAULTS }\n writeMode(this.settings.mode)\n writeSetting('blur', this.settings.blur)\n writeSetting('frost', this.settings.frost)\n writeSetting('brightness', this.settings.brightness)\n if (this.enabled) this.applySettings()\n this.publish()\n }\n\n /** Re-read every knob from localStorage into memory. */\n private reloadSettings(): void {\n this.settings = {\n mode: readMode(),\n blur: readSetting('blur'),\n frost: readSetting('frost'),\n brightness: readSetting('brightness'),\n }\n }\n\n private buildSnapshot(): GlassRowState {\n return { ...this.settings, enabled: this.enabled, dark: this.dark }\n }\n\n private publish(): void {\n this.snapshot = this.buildSnapshot()\n for (const listener of this.listeners) listener()\n }\n\n private sync(): void {\n if (this.enabled) this.mount()\n else this.unmount()\n this.publish()\n }\n\n /** Write the knob-driven CSS variables and mode attributes onto <html>. */\n private applySettings(): void {\n const style = document.documentElement.style\n style.setProperty('--dsh-glass-blur', `${this.settings.blur}px`)\n // Frost 0-100 → a 0-1.4 alpha multiplier (50 = 1x). Capped so max frost\n // stays translucent frosted glass instead of collapsing to a solid slab.\n style.setProperty('--dsh-glass-frost', String(Math.min(this.settings.frost / 50, 1.4)))\n // Backdrop brightness: dark mode darkens (0 = pure black, 50 = off),\n // light mode brightens (50 = off, 100 = pure white) — the knob's range\n // and the mix direction both follow the resolved scheme. The body\n // background rule mixes these fractions straight into the solid ground.\n const dark = this.dark\n style.setProperty('--dsh-glass-brightness-black', String(dark ? Math.max(0, (50 - this.settings.brightness) / 50) : 0))\n style.setProperty('--dsh-glass-brightness-white', String(dark ? 0 : Math.max(0, (this.settings.brightness - 50) / 50)))\n\n // Rendering mode: the float rules key off data-dsh-glass-float; the\n // compat (generic glass) rules key off data-dsh-glass-compat.\n const compat = this.settings.mode === 'compat'\n document.documentElement.toggleAttribute(GLASS_FLOAT_ATTRIBUTE, !compat)\n document.documentElement.toggleAttribute(GLASS_COMPAT_ATTRIBUTE, compat)\n }\n\n private mount(): void {\n this.ensureStyle()\n document.documentElement.setAttribute(GLASS_ATTRIBUTE, '')\n this.applySettings()\n this.ensureFades()\n if (this.seamDisposer === undefined) this.seamDisposer = startGlassSeamStamper()\n }\n\n private unmount(): void {\n document.documentElement.removeAttribute(GLASS_ATTRIBUTE)\n document.documentElement.removeAttribute(GLASS_FLOAT_ATTRIBUTE)\n document.documentElement.removeAttribute(GLASS_COMPAT_ATTRIBUTE)\n for (const node of document.querySelectorAll('[data-dsh-glass-fade]')) node.remove()\n this.seamDisposer?.()\n this.seamDisposer = undefined\n this.releaseStyle()\n }\n\n /** Mount the glass stylesheet <style> tag (lazy — first enable only;\n * re-append when toggling back on). The CSS text ships in the bundle as\n * `GLASS_CSS_TEXT` (see `glass-css.gen.ts`), so no document work happens\n * while the layer is off and only a detached/re-attached tag marks the\n * on/off boundary after the first mount. */\n private ensureStyle(): void {\n if (glassStyleTag !== null) {\n document.head.append(glassStyleTag)\n return\n }\n const tag = document.createElement('style')\n tag.dataset.plugin = GLASS_STYLE_PLUGIN\n tag.dataset.pluginCss = GLASS_STYLE_TAG_ID\n tag.textContent = GLASS_CSS_TEXT\n document.head.append(tag)\n glassStyleTag = tag\n }\n\n /** Remove the lazily-mounted stylesheet tag (the layer's CSS leaves the\n * document with it; the body attribute removal already made every rule\n * inert). */\n private releaseStyle(): void {\n glassStyleTag?.remove()\n glassStyleTag = null\n }\n\n /** Insert the page-edge fade bands (or reuse the existing ones). */\n private ensureFades(): void {\n if (document.querySelector('[data-dsh-glass-fade]') !== null) return\n const holder = document.createElement('div')\n holder.innerHTML = FADE_MARKUP\n for (const node of Array.from(holder.children)) {\n if (node instanceof HTMLElement) document.body.append(node)\n }\n }\n}\n","/**\n * Catppuccin glass settings row — registered into the General settings\n * section (`settings.general.item`, right under the Catppuccin flavour row).\n * Holds the master on/off switch plus every glass knob: mode (mica /\n * compatibility), blur, frost and backdrop brightness. Every write goes\n * straight through to the glass layer, so the skin moves live.\n */\nimport { useRef, useState, useSyncExternalStore } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { SETTINGS_DEFAULTS, type GlassRowState } from './glass-layer.ts'\nimport type { CatppuccinKey } from '../locales.ts'\nimport css from './GlassRow.module.css'\n\n/** Injected business face: the layer state seat plus every knob write. */\nexport interface GlassRowInjected {\n /** Current layer state snapshot. */\n getState: () => GlassRowState\n /** Subscribe to layer state changes. Returns the disposer. */\n subscribe: (listener: () => void) => () => void\n /** Switch the glass layer on or off. */\n setEnabled: (enabled: boolean) => void\n /** Set the rendering mode ('mica' floating cards or 'compat' stock layout). */\n setMode: (mode: 'mica' | 'compat') => void\n /** Set the glass blur radius, px. */\n setBlur: (value: number) => void\n /** Set the glass frost amount, 0-100. */\n setFrost: (value: number) => void\n /** Set the backdrop brightness, 0-100. */\n setBrightness: (value: number) => void\n /** Restore every knob to the shipped defaults. */\n resetDefaults: () => void\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type GlassRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'> & GlassRowInjected\n\n/** One slider + number box, wired to a single value. */\nfunction Knob(props: {\n label: string\n value: number\n min: number\n max: number\n step: number\n unit: string\n onChange: (value: number) => void\n}): React.JSX.Element {\n const { label, value, min, max, step, unit, onChange } = props\n const clamp = (n: number): number => Math.min(max, Math.max(min, Number.isFinite(n) ? n : min))\n return (\n <label className={css.knob}>\n <span className={css.knobLabel}>{label}</span>\n <input\n type=\"range\"\n className={css.slider}\n min={min}\n max={max}\n step={step}\n value={value}\n // Item Z: the raw number is announced without its unit otherwise. The\n // qualitative tier names stay out of the locale dictionaries on purpose\n // (7 languages × 3 knobs of invented copy buys little over parity).\n aria-valuetext={`${value}${unit}`}\n onChange={(e) => { onChange(clamp(Number(e.target.value))) }}\n />\n <span className={css.numberWrap}>\n <input\n type=\"number\"\n className={css.number}\n min={min}\n max={max}\n step={step}\n value={value}\n onChange={(e) => { onChange(clamp(Number(e.target.value))) }}\n />\n <span className={css.unit}>{unit}</span>\n </span>\n </label>\n )\n}\n\n/** A two-option segmented picker with roving tabindex (item AA): only the\n * selected cell is tabbable, Arrow/Home/End move focus WITHOUT selecting,\n * and Enter/Space (or click) commits — the WAI-ARIA roving-tabindex\n * pattern for segmented controls. */\nfunction Segmented<T extends string>(props: {\n label: string\n value: T\n options: readonly { id: T; label: string }[]\n onSelect: (value: T) => void\n}): React.JSX.Element {\n const { label, value, options, onSelect } = props\n const [focused, setFocused] = useState<T | null>(null)\n const refs = useRef(new Map<T, HTMLButtonElement>())\n\n // The roving tab stop. `value` may match NO option (the preset group gets ''\n // when the knobs are hand-tuned), and `option.id === value` would then leave\n // every cell at tabIndex -1 — the group silently drops out of the tab order\n // and keyboard users cannot reach the presets at all (audit F3). Fall back to\n // the first cell so the group always keeps exactly one tab stop.\n const matchesValue = options.some((option) => option.id === value)\n const anchor = focused ?? (matchesValue ? value : options[0]?.id)\n\n const moveFocus = (direction: 1 | -1 | 'home' | 'end'): void => {\n const current = anchor\n const index = options.findIndex((option) => option.id === current)\n let next: number\n if (direction === 'home') next = 0\n else if (direction === 'end') next = options.length - 1\n else next = Math.min(options.length - 1, Math.max(0, index + direction))\n const target = options[next]\n if (target === undefined) return\n setFocused(target.id)\n refs.current.get(target.id)?.focus()\n }\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>): void => {\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n moveFocus(-1)\n break\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n moveFocus(1)\n break\n case 'Home':\n event.preventDefault()\n moveFocus('home')\n break\n case 'End':\n event.preventDefault()\n moveFocus('end')\n break\n }\n }\n\n return (\n <div className={css.segmented} role=\"group\" aria-label={label}>\n {options.map((option) => (\n <button\n key={option.id}\n ref={(node) => {\n if (node === null) refs.current.delete(option.id)\n else refs.current.set(option.id, node)\n }}\n type=\"button\"\n className={option.id === value ? css.segActive : css.seg}\n aria-pressed={option.id === value}\n tabIndex={option.id === anchor ? 0 : -1}\n onFocus={() => { setFocused(option.id) }}\n onBlur={() => { setFocused((now) => (now === option.id ? null : now)) }}\n onKeyDown={onKeyDown}\n onClick={() => { onSelect(option.id) }}\n >\n {option.label}\n </button>\n ))}\n </div>\n )\n}\n\n/** One-click material presets — blur/frost/brightness triples the row applies\n * through the existing setters (the debounced persist coalesces the burst\n * into one Host write). Brightness stays neutral (50) so every preset works\n * in both schemes; the sliders remain for fine tuning. */\nconst GLASS_PRESETS: readonly { id: string; key: CatppuccinKey; blur: number; frost: number; brightness: number }[] = [\n { id: 'clear', key: 'glass.presetClear', blur: 0, frost: 8, brightness: 50 },\n { id: 'standard', key: 'glass.presetStandard', blur: SETTINGS_DEFAULTS.blur, frost: SETTINGS_DEFAULTS.frost, brightness: SETTINGS_DEFAULTS.brightness },\n { id: 'frosted', key: 'glass.presetFrosted', blur: 12, frost: 45, brightness: 50 },\n]\n\n/**\n * Render the glass row: title, the master switch, and — while enabled — the\n * mode picker and every knob.\n * @param props - composed slot props.\n * @returns the General section row.\n */\nexport function GlassRow({ t, getState, subscribe, setEnabled, setMode, setBlur, setFrost, setBrightness, resetDefaults }: GlassRowProps): React.JSX.Element {\n const state = useSyncExternalStore(subscribe, getState)\n const { enabled, mode, blur, frost, brightness, dark } = state\n\n // The brightness knob only ever offers the half that makes sense for the\n // resolved scheme: dark mode darkens (0-50), light mode brightens (50-100).\n const bgMin = dark ? 0 : 50\n const bgMax = dark ? 50 : 100\n const bgDisplay = Math.min(bgMax, Math.max(bgMin, brightness))\n\n // The preset whose knobs exactly match the live state (none = custom).\n const activePreset = GLASS_PRESETS.find(\n (p) => p.blur === blur && p.frost === frost && p.brightness === brightness,\n )?.id ?? ''\n\n return (\n <div className={css.group}>\n <div className={css.title}>\n {t('glass.title')}\n <span\n role=\"img\"\n aria-label={t('glass.helpLabel')}\n title={t('glass.help')}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n cursor: 'help',\n userSelect: 'none',\n marginLeft: 6,\n }}\n >\n ?\n </span>\n </div>\n <div className={css.description}>{t('glass.description')}</div>\n <div className={css.controls}>\n <div className={css.row}>\n <span className={css.rowLabel}>{t('glass.enable')}</span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t('glass.enable')}\n className={enabled ? css.toggleOn : css.toggle}\n onClick={() => { setEnabled(!enabled) }}\n >\n <span className={css.check} aria-hidden=\"true\">{enabled ? '✓' : ''}</span>\n </button>\n </div>\n {enabled && (\n <>\n <div className={css.row}>\n <span className={css.rowLabel}>{t('glass.mode')}</span>\n <Segmented\n label={t('glass.mode')}\n value={mode}\n options={[\n { id: 'mica', label: t('glass.modeMica') },\n { id: 'compat', label: t('glass.modeCompat') },\n ]}\n onSelect={setMode}\n />\n </div>\n <div className={css.rowHint}>{t('glass.modeHint')}</div>\n <div className={css.row}>\n <span className={css.rowLabel}>{t('glass.presets')}</span>\n <Segmented\n label={t('glass.presets')}\n value={activePreset}\n options={GLASS_PRESETS.map((p) => ({ id: p.id, label: t(p.key) }))}\n onSelect={(id) => {\n const preset = GLASS_PRESETS.find((p) => p.id === id)\n if (preset === undefined) return\n setBlur(preset.blur)\n setFrost(preset.frost)\n setBrightness(preset.brightness)\n }}\n />\n </div>\n <Knob label={t('glass.blur')} value={blur} min={0} max={40} step={0.5} unit=\"px\" onChange={setBlur} />\n <Knob label={t('glass.frost')} value={frost} min={0} max={100} step={1} unit=\"%\" onChange={setFrost} />\n <Knob label={t('glass.brightness')} value={bgDisplay} min={bgMin} max={bgMax} step={1} unit=\"%\" onChange={setBrightness} />\n <div className={css.knobHint}>\n {t(dark ? 'glass.brightnessHintDark' : 'glass.brightnessHintLight')}\n </div>\n <div className={css.row}>\n <button type=\"button\" className={css.resetButton} onClick={() => { resetDefaults() }}>\n {t('glass.reset')}\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n )\n}\n","/**\n * \"Feedback & support\" settings row — the section's closing row: a link to\n * the GitHub issue tracker and a link to the repository (the polite star\n * ask). Added 2026-10-11: the plugin previously had NO in-app path to either\n * — a user who hit a problem had to already know the repo exists.\n *\n * No injected face on purpose: the row is pure copy plus two static URLs, so\n * it registers without an `inject` factory (the locale seat is all it needs)\n * and renders identically in both homes — the General settings section and\n * the plugin's own detail page in the Plugin manager (`detail-card.tsx`).\n *\n * Both links open in a new tab/window (`target=\"_blank\"`): without it the\n * click would navigate the DSH UI itself away from the app.\n */\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\n\n/**\n * GitHub repository — where a star lands. Keep the `-theme` name: it is the\n * current repo name (the pre-rename URL only redirects), and only COMPLETE\n * GitHub URLs use it (AGENTS.md「项目身份速览:三套名字」).\n */\nexport const REPO_URL = 'https://github.com/NoNameLeGo/dsh-catppuccin-theme'\n\n/** GitHub issue tracker — where feedback lands. */\nexport const ISSUES_URL = `${REPO_URL}/issues`\n\n/** Full component props: runtime share + locale seat. No injected face. */\nexport type LinksRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'>\n\n/** The row's links: token-coloured, underlined, quiet. */\nconst linkStyle: React.CSSProperties = {\n color: 'var(--dsw-alias-state-business-primary)',\n fontSize: 12,\n lineHeight: '18px',\n textDecoration: 'underline',\n textUnderlineOffset: 3,\n}\n\n/**\n * Render the feedback row: a title and the two links.\n * @param props - composed slot props.\n * @returns the row element tree.\n */\nexport function LinksRow({ t }: LinksRowProps): React.JSX.Element {\n return (\n <div style={{ borderBottom: '1px solid var(--dsw-alias-border-l2)', display: 'flex', flexDirection: 'column', gap: '10px', padding: '16px 0' }}>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 14, lineHeight: '22px' }}>\n {t('links.title')}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}>\n <a href={ISSUES_URL} target=\"_blank\" rel=\"noreferrer noopener\" style={linkStyle}>\n {t('links.issue')}\n </a>\n <a href={REPO_URL} target=\"_blank\" rel=\"noreferrer noopener\" style={linkStyle}>\n {t('links.star')}\n </a>\n </div>\n </div>\n )\n}\n","/**\n * Update-check settings row — one General-section preference row that asks\n * the Host's `/catppuccin/check-update` route for the latest published npm\n * version and reports whether this install is current. Detection is Host-side\n * (Node fetch, no CORS, profile probe included); the row renders the verdict\n * and, when an update is available, offers the copyable CLI upgrade command\n * whose profile name the Host already probed. Upgrading itself stays a\n * terminal action (`dsh plugin … add @latest`) — the row never touches the\n * profile workspace.\n *\n * Beyond the check button the row carries:\n * - the auto-check switch (item H) and the release-channel segmented pick\n * (item I), both persisted through the durable state;\n * - an automatic retry 30s after a failed check (item V) with a countdown;\n * - a conflict banner (item C/X) when a durable write from another window\n * superseded a local change (\"另一窗口已更新,本地改动未保存\");\n * - the latest auto-check verdict (item H) surfaced on mount;\n * - a \"?\" help affordance (item J, native `title` tooltip).\n */\nimport { useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { UpdateCheckPayload, UpdateErrorCode, UpdateChannel } from '../update-check.ts'\nimport type { CatppuccinKey } from './locales.ts'\n\n/** Auto-retry scheduled after a failed check (item V): one retry after 30s,\n * then it stops — the discipline lives here in the row, never in a hanging\n * route request. */\nexport const UPDATE_RETRY_AFTER_MS = 30_000\n\n/** Injected business face of the row (assembled in apply). */\nexport interface UpdateRowInjected {\n /** Ask the Host for the update verdict (same-origin fetch of the route).\n * The channel preference rides the query string (item I). */\n check: (channel: UpdateChannel) => Promise<UpdateCheckPayload>\n /** Whether automatic checks are on (item H). */\n autoCheck: () => boolean\n /** Set the auto-check preference (persists durably + re-arms timers). */\n setAutoCheck: (value: boolean) => void\n /** The persisted release channel (item I). */\n channel: () => UpdateChannel\n /** Set the release channel (persists durably). */\n setChannel: (channel: UpdateChannel) => void\n /** Subscribe to preference changes (auto-check / channel). */\n subscribePrefs: (listener: () => void) => () => void\n /** The latest auto-check verdict, or null before the first one (item H). */\n lastAutoResult: () => UpdateCheckPayload | null\n /** Subscribe to durable-write conflict notices (item C/X). */\n subscribeConflict: (listener: () => void) => () => void\n /** Number of conflicts this session has seen (item C/X). */\n conflictCount: () => number\n /** The active DSH locale id — for locale-aware formatting (timestamps).\n * `toLocaleString()` with no argument uses the BROWSER locale, which drifts\n * from the interface language as soon as the user picks one in Settings. */\n activeLocale: () => string\n /** Subscribe to locale switches, so a language change re-formats the row. */\n subscribeLocale: (listener: () => void) => () => void\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type UpdateRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'catppuccin'> & UpdateRowInjected\n\n/** One phase of the row's interaction. */\ntype Phase = 'idle' | 'checking' | 'done'\n\n/** Copy the upgrade command; falls back to no-op when the clipboard is unavailable. */\nasync function copyCommand(text: string): Promise<boolean> {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n return false\n }\n}\n\n/** Map a stable error code to its locale key (unknown codes fall back to the generic message). */\nfunction errorKey(code: UpdateErrorCode | undefined): CatppuccinKey {\n switch (code) {\n case 'registry-unreachable': return 'update.err.registry'\n case 'registry-http': return 'update.err.http'\n case 'no-dist-tags': return 'update.err.noTags'\n case 'invalid-response': return 'update.err.invalid'\n case 'network.local': return 'update.err.networkLocal'\n case 'network.upstream': return 'update.err.networkUpstream'\n default: return 'update.failed'\n }\n}\n\nconst switchBase: React.CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n flex: 'none',\n width: 44,\n height: 24,\n padding: 0,\n border: '1px solid var(--dsw-alias-border-l2)',\n borderRadius: 12,\n background: 'var(--dsw-alias-bg-layer-2)',\n cursor: 'pointer',\n}\n\nconst knobStyle: React.CSSProperties = {\n position: 'absolute',\n top: 3,\n left: 3,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n background: 'var(--dsw-alias-label-tertiary)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 10,\n lineHeight: 1,\n transition: 'transform 0.18s cubic-bezier(0.4, 0, 0.2, 1)',\n}\n\nconst buttonStyle: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n padding: '6px 12px',\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l1)',\n background: 'transparent',\n color: 'var(--dsw-alias-label-primary)',\n cursor: 'pointer',\n font: 'inherit',\n}\n\n/**\n * Render the update-check row: title, description, auto-check switch,\n * channel pick, a check button, and the verdict once checked.\n * @param props - composed slot props.\n * @returns the row element tree.\n */\nexport function UpdateRow({\n t,\n check,\n autoCheck,\n setAutoCheck,\n channel,\n setChannel,\n subscribePrefs,\n lastAutoResult,\n subscribeConflict,\n conflictCount,\n activeLocale,\n subscribeLocale,\n}: UpdateRowProps): React.JSX.Element {\n const [phase, setPhase] = useState<Phase>('idle')\n const [payload, setPayload] = useState<UpdateCheckPayload | null>(null)\n const [copied, setCopied] = useState(false)\n const autoCheckOn = useSyncExternalStore(subscribePrefs, autoCheck)\n const channelValue = useSyncExternalStore(subscribePrefs, channel)\n const conflicts = useSyncExternalStore(subscribeConflict, conflictCount)\n // The timestamp follows the DSH locale, not the browser: the two only agree\n // until the user picks a language in Settings (2026-09-21 audit).\n const locale = useSyncExternalStore(subscribeLocale, activeLocale)\n const [dismissedConflicts, setDismissedConflicts] = useState(0)\n // Item V: ONE automatic retry after a failure, 30s later (\"仍失败则停\").\n const [retryRemaining, setRetryRemaining] = useState<number | null>(null)\n const retryTimer = useRef<number | undefined>(undefined)\n const tickerTimer = useRef<number | undefined>(undefined)\n // Auto-retries already spent since the last user-initiated check. The retry\n // itself calls `runCheck` (not `runManualCheck`), so a retry that fails\n // again hits this guard and stops instead of re-scheduling forever.\n const retriesUsed = useRef(0)\n const mounted = useRef(true)\n\n /** Drop a pending auto-retry (its timeout and its countdown ticker). */\n const cancelRetry = (): void => {\n if (retryTimer.current !== undefined) {\n window.clearTimeout(retryTimer.current)\n retryTimer.current = undefined\n }\n if (tickerTimer.current !== undefined) {\n window.clearInterval(tickerTimer.current)\n tickerTimer.current = undefined\n }\n setRetryRemaining(null)\n }\n\n // The channel is resolved at CALL time (audit F6): the default used to be the\n // render-closure's `channelValue`, so the 30 s auto-retry — and any check\n // fired from a stale render — queried the channel that was current when the\n // handler was created, not the one the user has since picked.\n const runCheck = async (withChannel?: UpdateChannel): Promise<void> => {\n cancelRetry()\n setPhase('checking')\n setCopied(false)\n let next: UpdateCheckPayload\n try {\n next = await check(withChannel ?? channel())\n } catch {\n next = { ok: false, code: 'network.local', error: 'network.local' }\n }\n setPayload(next)\n setPhase('done')\n if (!next.ok && retriesUsed.current === 0) {\n retriesUsed.current = 1\n const target = Date.now() + UPDATE_RETRY_AFTER_MS\n setRetryRemaining(UPDATE_RETRY_AFTER_MS / 1000)\n const ticker = window.setInterval(() => {\n const remaining = Math.max(0, Math.ceil((target - Date.now()) / 1000))\n setRetryRemaining(remaining)\n if (remaining <= 0) {\n window.clearInterval(ticker)\n tickerTimer.current = undefined\n }\n }, 1000)\n tickerTimer.current = ticker\n retryTimer.current = window.setTimeout(() => {\n if (mounted.current) void runCheck()\n else cancelRetry()\n }, UPDATE_RETRY_AFTER_MS)\n }\n }\n\n /** A user-initiated check: re-arms the one auto-retry budget (item V). */\n const runManualCheck = (): void => {\n retriesUsed.current = 0\n void runCheck()\n }\n\n useEffect(() => {\n mounted.current = true\n return () => {\n mounted.current = false\n if (retryTimer.current !== undefined) window.clearTimeout(retryTimer.current)\n if (tickerTimer.current !== undefined) window.clearInterval(tickerTimer.current)\n }\n }, [])\n\n const autoResult = lastAutoResult()\n const localInstall = payload?.ok === true && payload.installSource !== undefined\n && payload.installSource !== 'registry'\n // DSH Desktop adapts the copy: its target profile comes from the Desktop\n // service and the hint/restart text says so, while standard dsh web keeps\n // the terminal copy.\n const isDesktop = payload?.ok === true && payload.env === 'desktop'\n // The official Electron shell has no CLI path a user can reach (its Plugins\n // page is the only way: delete → re-add the package name), so it gets the\n // bare `pkg@tag` spec plus the page instructions instead of a shell command.\n const officialDesktop = payload?.ok === true && payload.shell === 'official-desktop'\n const upgradeValue = payload?.ok === true\n ? (officialDesktop ? payload.updateSpec : payload.updateCommand)\n : undefined\n const showConflict = conflicts > dismissedConflicts\n\n return (\n <div style={{ borderBottom: '1px solid var(--dsw-alias-border-l2)', display: 'flex', flexDirection: 'column', gap: '10px', padding: '16px 0' }}>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 14, lineHeight: '22px', display: 'flex', alignItems: 'center' }}>\n {t('update.title')}\n <span\n role=\"img\"\n aria-label={t('update.helpLabel')}\n title={t('update.help')}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n borderRadius: '50%',\n border: '1px solid var(--dsw-alias-border-l2)',\n color: 'var(--dsw-alias-label-tertiary)',\n fontSize: 11,\n lineHeight: 1,\n cursor: 'help',\n userSelect: 'none',\n marginLeft: 6,\n flex: 'none',\n }}\n >\n ?\n </span>\n </div>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.description')}\n </div>\n\n {/* Conflict banner (item C/X): another window's durable write won. */}\n {showConflict && (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center', padding: '6px 10px', borderRadius: 8, border: '1px solid var(--dsw-alias-border-l2)', background: 'var(--dsw-alias-state-business-tertiary)' }}>\n <span style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.conflict')}\n </span>\n <button\n type=\"button\"\n aria-label={t('update.conflictDismiss')}\n onClick={() => { setDismissedConflicts(conflicts) }}\n style={{ ...buttonStyle, padding: '2px 8px', fontSize: 12 }}\n >\n ✕\n </button>\n </div>\n )}\n\n {/* Auto-check + channel preferences (items H/I). */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px', alignItems: 'center' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.autoCheck')}\n </span>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={autoCheckOn}\n aria-label={t('update.autoCheck')}\n onClick={() => { setAutoCheck(!autoCheckOn) }}\n style={{ ...switchBase, background: autoCheckOn ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-bg-layer-2)' }}\n >\n <span aria-hidden=\"true\" style={{ ...knobStyle, transform: autoCheckOn ? 'translateX(22px)' : undefined, background: autoCheckOn ? 'var(--dsw-alias-bg-layer-1)' : 'var(--dsw-alias-label-tertiary)' }}>\n {autoCheckOn ? '✓' : ''}\n </span>\n </button>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.channel')}\n </span>\n <div style={{ display: 'inline-flex', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8, overflow: 'hidden' }} role=\"group\" aria-label={t('update.channel')}>\n {(['latest', 'beta'] as const).map((option, index) => (\n <button\n key={option}\n type=\"button\"\n aria-pressed={channelValue === option}\n onClick={() => { setChannel(option) }}\n style={{\n height: 26,\n padding: '0 12px',\n border: 'none',\n borderLeft: index > 0 ? '1px solid var(--dsw-alias-border-l2)' : undefined,\n background: channelValue === option ? 'var(--dsw-alias-state-business-tertiary)' : 'transparent',\n color: channelValue === option ? 'var(--dsw-alias-state-business-primary)' : 'var(--dsw-alias-label-secondary)',\n fontSize: 12,\n lineHeight: '18px',\n cursor: 'pointer',\n }}\n >\n {t(option === 'latest' ? 'update.channelLatest' : 'update.channelBeta')}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n {/* Auto-check verdict surfaced at mount (item H). */}\n {autoResult?.ok === true && autoResult.outdated === true && autoResult.latest !== undefined && (\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.autoAvailable')} <strong>{autoResult.latest}</strong>\n </div>\n )}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <button type=\"button\" disabled={phase === 'checking'} onClick={runManualCheck} style={{ ...buttonStyle, cursor: phase === 'checking' ? 'default' : 'pointer', opacity: phase === 'checking' ? 0.6 : 1 }}>\n {phase === 'checking' ? t('update.checking') : t('update.check')}\n </button>\n {payload?.ok === true && payload.current !== undefined && (\n <span style={{ color: 'var(--dsw-alias-label-secondary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.current')} {payload.current}\n </span>\n )}\n {payload?.ok === true && payload.checkedAt !== undefined && (\n <span style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 11, lineHeight: '18px' }}>\n {t('update.checkedAt')} {new Date(payload.checkedAt).toLocaleString(locale)}\n </span>\n )}\n </div>\n\n {phase === 'done' && payload !== null && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>\n {payload.ok === true ? (\n payload.outdated === true && payload.latest !== undefined ? (\n <>\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.available')} <strong>{payload.latest}</strong>\n </div>\n {upgradeValue !== undefined && (\n <>\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {officialDesktop\n ? t('update.commandHintOfficialDesktop')\n : isDesktop\n ? t('update.commandHintDesktop').replace('{profile}', payload.profile ?? '')\n : payload.profileDetected === true && payload.profile !== undefined\n ? t('update.commandHintDetected').replace('{profile}', payload.profile)\n : t('update.commandHint')}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <code style={{\n flex: '1 1 260px',\n padding: '6px 10px',\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l1)',\n background: 'var(--dsw-alias-bg-layer-1)',\n color: 'var(--dsw-alias-label-primary)',\n fontSize: 12,\n lineHeight: '18px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',\n }}>\n {upgradeValue}\n </code>\n <button\n type=\"button\"\n onClick={() => { void copyCommand(upgradeValue).then(setCopied) }}\n style={{ ...buttonStyle, cursor: 'pointer' }}\n >\n {copied ? t('update.copied') : t(officialDesktop ? 'update.copySpec' : 'update.copy')}\n </button>\n </div>\n {localInstall && (\n <div style={{ color: 'var(--dsw-alias-label-warning, var(--dsw-alias-label-tertiary))', fontSize: 12, lineHeight: '18px' }}>\n {t('update.localInstall')}\n </div>\n )}\n <div style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t(isDesktop ? 'update.restartHintDesktop' : 'update.restartHint')}\n </div>\n </>\n )}\n </>\n ) : (\n <div style={{ color: 'var(--dsw-alias-label-primary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.upToDate')}\n </div>\n )\n ) : (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', alignItems: 'center' }}>\n <span style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t(errorKey(payload.code))}\n </span>\n {retryRemaining !== null && retryRemaining > 0 && (\n <span style={{ color: 'var(--dsw-alias-label-tertiary)', fontSize: 12, lineHeight: '18px' }}>\n {t('update.retryHint').replace('{s}', String(retryRemaining))}\n </span>\n )}\n <button type=\"button\" onClick={runManualCheck} style={{ ...buttonStyle, cursor: 'pointer' }}>\n {t('update.retry')}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}","/**\n * Plugins-page card — the settings section in the middle of this plugin's own\n * detail page in the Plugin manager (the block ABOVE \"包含的组件\").\n *\n * Why this file exists (evidence, 2026-10-03, official shell 0.2.0-rc.2): the\n * bundle detail page renders\n * `renderSlot('plugins.bundle.config', { view: 'page' }, { entryKey: pkg.name })`\n * (`dsh-client-ui-plugin-manager`), and that `[data-plugin-config]` section\n * exists ONLY when a plugin registers into it. The page's config ledger reads\n * `ctx.slots.entries('plugins.bundle.config')`, so an unregistered slot leaves\n * the page with no settings area at all — which is what this plugin showed\n * before this card. Two upstream references do the same thing:\n * - official `ui-settings-agent-loop` / `ui-settings-shell` register\n * `plugins.item` (the official-plugin card) with `id` / `order` / `label`;\n * - community `dsh-context` (0.60.0) registers THIS slot with\n * `key = its package name` — the shape the screenshot showed.\n * Both wrap the registration in `configForms.whileServed([ns], …)`, which is\n * also why this card appears/disappears with the namespace instead of leaving\n * an empty section behind.\n *\n * `autoGenerate` is NOT the switch here: it is only reported to clients (the\n * host's `describe()` does not filter on it and the page's `formFor()` only\n * looks the namespace up), and registering the slot above is what makes the\n * section render. The Host half keeps `configure({ auto: false })` because\n * this plugin genuinely ships its own UI.\n *\n * Not a second implementation: the card renders the SAME four rows the\n * General section shows and is handed the same injected faces, so both homes\n * read and write the one durable section (`CATPPUCCIN_ENTRY_ID`). The only\n * cost of the second home is that the rows exist twice in the DOM when\n * both are open — each instance subscribes for itself, so no state is shared\n * behind the framework's back (the feedback row has no state at all).\n */\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CatppuccinRow, type CatppuccinRowInjected } from './CatppuccinRow.tsx'\nimport { GlassRow, type GlassRowInjected } from './glass/glass-row.tsx'\nimport { LinksRow } from './LinksRow.tsx'\nimport { UpdateRow, type UpdateRowInjected } from './UpdateRow.tsx'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n /**\n * One settings page on a BUNDLE's detail page in the Plugin manager,\n * keyed by the bundle's PACKAGE NAME (`{ entryKey: pkg.name }`) — for this\n * plugin `@nonamelego/dsh-catppuccin`, NOT the profile entry id the\n * namespace is keyed by (`CATPPUCCIN_ENTRY_ID`). The section renders only\n * while an entry is registered; `slots.inject` waits for this declaration,\n * so a host without the Plugin manager simply never fires.\n *\n * Declared here because this repo's devDependency (`dsh-client-ui-settings`\n * at the 0.1.7 line) predates the Plugin manager while the RUNNING host\n * (0.2.0-rc.2) has it. A future devDependency bump that carries this member\n * merges with this one and must then be reconciled (identical duplicates\n * merge silently; a different shape is a compile error — that error is the\n * signal to delete this declaration).\n */\n 'plugins.bundle.config': {\n kind: 'keyed'\n scope: 'root'\n }\n }\n}\n\n/** Injected business face of the card: the three rows' own faces, unchanged. */\nexport interface CatppuccinDetailCardInjected {\n /** Catppuccin flavour row (registered themes + pick). */\n flavor: CatppuccinRowInjected\n /** Glass-layer row (enable flag + knobs). */\n glass: GlassRowInjected\n /** Update-check row (version, channel, check button). */\n update: UpdateRowInjected\n}\n\n/** Full component props: runtime share + locale seat + injected face. */\nexport type CatppuccinDetailCardProps =\n PropsRuntime<'plugins.bundle.config'> & PropsLocale<'catppuccin'> & CatppuccinDetailCardInjected\n\n/**\n * Render the four preference rows on the plugin's own detail page.\n *\n * The rows carry their own title, help affordance and spacing (a bottom\n * border each), so the card is a plain column — the page owns the section\n * chrome (`[data-plugin-config]`).\n * @param props - the injected faces plus the framework seats.\n * @returns the stacked rows.\n */\nexport function CatppuccinDetailCard(props: CatppuccinDetailCardProps): React.JSX.Element {\n return (\n <div data-catppuccin-detail-card style={{ display: 'flex', flexDirection: 'column' }}>\n <CatppuccinRow {...props.flavor} t={props.t} />\n <GlassRow {...props.glass} t={props.t} />\n <UpdateRow {...props.update} t={props.t} />\n <LinksRow t={props.t} />\n </div>\n )\n}\n","/**\n * Catppuccin settings-row copy. The zh dictionary is the key-set source of\n * truth; every other dictionary mirrors it (guarded by tests/locales.spec.ts\n * asserting key-set equality against `zh`).\n */\n\n/** Simplified Chinese dictionary. */\nexport const zh = {\n 'row.title': 'Catppuccin 主题',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha 四款配色,一键切换。',\n 'row.off': '跟随系统',\n 'row.helpLabel': '关于 Catppuccin 主题',\n 'row.help': 'Catppuccin 社区出品的四款配色:Latte(浅色)、Frappé / Macchiato / Mocha(深色)。选择后立即生效并持久保存。',\n 'row.shikiStyle': '代码高亮风格',\n 'row.shikiDefault': '默认',\n 'row.shikiItalicComments': '柔和注释',\n 'row.overrides': '自定义覆盖',\n 'row.overridesHint': '按「--dsw-* 变量: 值」覆盖单个配色 token,例如 --dsw-static-blue-500: #89b4fa。键名与值都在失焦时生效,清空值即删除。',\n 'row.overridesEmpty': '暂无覆盖。点击「+ 添加」新增一条 token 覆盖。',\n 'row.overridesAdd': '添加',\n 'row.overridesRemove': '删除此覆盖',\n 'row.overridesKey': 'token 名称',\n 'row.overridesValue': 'token 值',\n 'flavor.latte.subtitle': '浅色',\n 'flavor.frappe.subtitle': '深色',\n 'flavor.macchiato.subtitle': '深色',\n 'flavor.mocha.subtitle': '深色',\n 'glass.title': '玻璃质感',\n 'glass.description': '顶栏、侧边栏、输入框、统计行、轨迹视图的磨砂玻璃效果,一键开关。',\n 'glass.helpLabel': '关于玻璃质感',\n 'glass.help': '在 Catppuccin 主题之上叠加磨砂玻璃皮肤:悬浮卡片(云母效果)或保持原版排版的兼容模式。模糊度、磨砂度、背景亮度均可调,并支持清透 / 标准 / 磨砂三档预设。云母效果会在顶栏、输入框等大面积区域做背景模糊,流式输出时较吃 GPU——在意性能请用兼容模式,或选「清透」预设。',\n 'glass.enable': '总开关',\n 'glass.mode': '模式',\n 'glass.modeMica': '云母效果',\n 'glass.modeCompat': '兼容模式',\n 'glass.modeHint': '云母效果把界面改成悬浮磨砂卡片;兼容模式保持原版排版,只换玻璃材质(不模糊大面积区域,性能更稳妥)',\n 'glass.presets': '预设',\n 'glass.presetClear': '清透',\n 'glass.presetStandard': '标准',\n 'glass.presetFrosted': '磨砂',\n 'glass.blur': '玻璃模糊度',\n 'glass.frost': '磨砂度',\n 'glass.brightness': '背景亮度',\n 'glass.brightnessHintDark': '深色模式:0 压暗至纯黑,50 原样',\n 'glass.brightnessHintLight': '浅色模式:50 原样,100 提亮至纯白',\n 'glass.reset': '还原默认值',\n 'update.title': '检查 Catppuccin 插件更新',\n 'update.description': '检测本插件(dsh-catppuccin)在 npm 上的最新版本,判断当前安装是否需要升级。',\n 'update.helpLabel': '关于更新检查',\n 'update.help': '向 npm registry 查询本插件的最新版本。开启「自动检查」后会在启动时与每 6 小时自动检查;渠道选 beta 可追踪预发布版本。',\n 'update.autoCheck': '自动检查更新',\n 'update.channel': '渠道',\n 'update.channelLatest': '稳定版',\n 'update.channelBeta': 'Beta 版',\n 'update.check': '检查更新',\n 'update.checking': '检查中…',\n 'update.current': '当前版本',\n 'update.upToDate': '已是最新版本 🎉',\n 'update.available': '发现新版本:',\n 'update.autoAvailable': '自动检查发现新版本:',\n 'update.commandHint': '在终端运行以下命令升级(把 web 换成你的 profile 名):',\n 'update.commandHintDetected': '已自动探测到 profile「{profile}」,在终端运行以下命令升级:',\n 'update.commandHintDesktop': '已检测到你在使用 DSH Desktop,目标 profile「{profile}」,请在 DSH 终端中运行以下命令升级:',\n 'update.commandHintOfficialDesktop': '已检测到官方桌面版(DeepSeek Harness 客户端):它没有命令行升级入口——请在**插件界面**里先删除本插件,再把下面的包名粘进「添加插件」重新安装。',\n 'update.restartHint': '升级完成后重启 dsh web 生效。',\n 'update.restartHintDesktop': '升级完成后重启 DSH Desktop 生效。',\n 'update.copy': '复制命令',\n 'update.copySpec': '复制包名',\n 'update.copied': '已复制 ✓',\n 'update.failed': '检查失败,请稍后重试。',\n 'update.retry': '重试',\n 'update.retryHint': '{s} 秒后自动重试…',\n 'update.checkedAt': '检查时间',\n 'update.localInstall': '检测到本地链接/源码安装,npm 升级命令可能不适用——请用 git pull 或重新构建。',\n 'update.conflict': '另一窗口已更新,本地改动未保存。',\n 'update.conflictDismiss': '关闭提示',\n 'update.err.registry': '无法连接 npm registry,请检查网络后重试。',\n 'update.err.http': 'npm registry 返回异常状态码,请稍后重试。',\n 'update.err.noTags': 'npm registry 未返回可用的版本标签。',\n 'update.err.invalid': 'npm registry 返回了无法解析的数据。',\n 'update.err.networkLocal': '无法连接插件宿主——请检查你的网络后刷新页面重试。',\n 'update.err.networkUpstream': 'npm registry 暂时不可用(请求超时),请稍后重试。',\n 'links.title': '反馈与支持',\n 'links.issue': '对 Catppuccin 外观插件有问题或建议?欢迎在 GitHub 提 Issue',\n 'links.star': '喜欢这个 Catppuccin 外观插件?点一个 Star ⭐',\n} as const\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin theme',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, one click away.',\n 'row.off': 'Follow system',\n 'row.helpLabel': 'About the Catppuccin theme',\n 'row.help': 'Four palettes from the Catppuccin community: Latte (light), Frappé / Macchiato / Mocha (dark). Applies instantly and persists.',\n 'row.shikiStyle': 'Code highlight style',\n 'row.shikiDefault': 'Default',\n 'row.shikiItalicComments': 'Soft comments',\n 'row.overrides': 'Custom overrides',\n 'row.overridesHint': 'Override individual colour tokens as \"--dsw-* variable: value\", e.g. --dsw-static-blue-500: #89b4fa. Both fields apply on blur; an empty value deletes the entry.',\n 'row.overridesEmpty': 'No overrides yet. Click \"+ Add\" to create one.',\n 'row.overridesAdd': 'Add',\n 'row.overridesRemove': 'Remove this override',\n 'row.overridesKey': 'Token name',\n 'row.overridesValue': 'Token value',\n 'flavor.latte.subtitle': 'Light',\n 'flavor.frappe.subtitle': 'Dark',\n 'flavor.macchiato.subtitle': 'Dark',\n 'flavor.mocha.subtitle': 'Dark',\n 'glass.title': 'Glassmorphism',\n 'glass.description': 'Frosted glass for the top bar, sidebar, composer, stats line and trajectory view — one click on/off.',\n 'glass.helpLabel': 'About glassmorphism',\n 'glass.help': 'A frosted-glass skin layered over the Catppuccin theme: floating cards (Mica) or the stock layout with a glass material (Compatibility). Blur, frost and backdrop brightness are tunable, with Clear / Standard / Frosted presets. Mica blurs large areas (top bar, composer), so it costs GPU while output streams — pick Compatibility or the Clear preset if that matters.',\n 'glass.enable': 'Master switch',\n 'glass.mode': 'Mode',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Compatibility',\n 'glass.modeHint': 'Mica restyles the UI into floating frosted cards; Compatibility keeps the stock layout and only swaps the material to glass (no large-area blur — the lighter option)',\n 'glass.presets': 'Presets',\n 'glass.presetClear': 'Clear',\n 'glass.presetStandard': 'Standard',\n 'glass.presetFrosted': 'Frosted',\n 'glass.blur': 'Glass blur',\n 'glass.frost': 'Frost',\n 'glass.brightness': 'Backdrop brightness',\n 'glass.brightnessHintDark': 'Dark mode: 0 fades to pure black, 50 unchanged',\n 'glass.brightnessHintLight': 'Light mode: 50 unchanged, 100 brightens to pure white',\n 'glass.reset': 'Reset to defaults',\n 'update.title': 'Check for Catppuccin plugin updates',\n 'update.description': 'Checks npm for the latest dsh-catppuccin release and whether this install is current.',\n 'update.helpLabel': 'About update checks',\n 'update.help': 'Queries the npm registry for the latest release of this plugin. With auto-check on, a check runs at startup and every 6 hours; the Beta channel also chases prereleases.',\n 'update.autoCheck': 'Auto-check for updates',\n 'update.channel': 'Channel',\n 'update.channelLatest': 'Stable',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Check for updates',\n 'update.checking': 'Checking…',\n 'update.current': 'Current version',\n 'update.upToDate': 'Up to date 🎉',\n 'update.available': 'New version available:',\n 'update.autoAvailable': 'Auto-check found a new version:',\n 'update.commandHint': 'Run this in a terminal to upgrade (replace web with your profile name):',\n 'update.commandHintDetected': 'Profile \"{profile}\" detected — run this in a terminal to upgrade:',\n 'update.commandHintDesktop': 'DSH Desktop detected — target profile \"{profile}\", run this in the DSH terminal to upgrade:',\n 'update.commandHintOfficialDesktop': 'Official desktop build detected (DeepSeek Harness client) — it has no CLI upgrade path: delete this plugin on the **Plugins** page, then paste the package name below into \"Add plugin\" to reinstall.',\n 'update.restartHint': 'Restart dsh web after the upgrade.',\n 'update.restartHintDesktop': 'Restart DSH Desktop after the upgrade.',\n 'update.copy': 'Copy command',\n 'update.copySpec': 'Copy package name',\n 'update.copied': 'Copied ✓',\n 'update.failed': 'Check failed — try again later.',\n 'update.retry': 'Retry',\n 'update.retryHint': 'Auto-retrying in {s}s…',\n 'update.checkedAt': 'Checked at',\n 'update.localInstall': 'This install is a local link/source checkout — the npm upgrade command may not apply; use git pull or rebuild instead.',\n 'update.conflict': 'Another window updated the settings — your local changes were not saved.',\n 'update.conflictDismiss': 'Dismiss',\n 'update.err.registry': 'Could not reach the npm registry — check your network and retry.',\n 'update.err.http': 'The npm registry returned an unexpected status code.',\n 'update.err.noTags': 'The npm registry returned no usable version tags.',\n 'update.err.invalid': 'The npm registry returned unparseable data.',\n 'update.err.networkLocal': 'Could not reach the plugin host — check your network, then refresh the page.',\n 'update.err.networkUpstream': 'The npm registry is temporarily unavailable (request timed out) — try again later.',\n 'links.title': 'Feedback & support',\n 'links.issue': 'Found a problem with the Catppuccin appearance plugin, or have an idea? Open an issue',\n 'links.star': 'Enjoying this Catppuccin appearance plugin? Star it on GitHub ⭐',\n}\n\n/** Japanese dictionary. */\nexport const ja: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin テーマ',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha の4色をワンクリックで切替。',\n 'row.off': 'システムに従う',\n 'row.helpLabel': 'Catppuccin テーマについて',\n 'row.help': 'Catppuccin コミュニティの4色: Latte(ライト)、Frappé / Macchiato / Mocha(ダーク)。選択直後に反映され、保存されます。',\n 'row.shikiStyle': 'コードハイライト',\n 'row.shikiDefault': 'デフォルト',\n 'row.shikiItalicComments': 'ソフトなコメント',\n 'row.overrides': 'カスタム上書き',\n 'row.overridesHint': '「--dsw-* 変数: 値」の形で個別トークンを上書きします。例: --dsw-static-blue-500: #89b4fa。フォーカスを外すと反映、空値で削除。',\n 'row.overridesEmpty': '上書きはまだありません。「+ 追加」で作成します。',\n 'row.overridesAdd': '追加',\n 'row.overridesRemove': 'この上書きを削除',\n 'row.overridesKey': 'トークン名',\n 'row.overridesValue': 'トークン値',\n 'flavor.latte.subtitle': 'ライト',\n 'flavor.frappe.subtitle': 'ダーク',\n 'flavor.macchiato.subtitle': 'ダーク',\n 'flavor.mocha.subtitle': 'ダーク',\n 'glass.title': 'ガラス質感',\n 'glass.description': 'トップバー・サイドバー・入力欄・ステータス行・軌跡ビューにすりガラス効果、ワンクリックで ON/OFF。',\n 'glass.helpLabel': 'ガラス質感について',\n 'glass.help': 'Catppuccin テーマの上に乗せるガラススキン: 浮遊カード(Mica)または原版レイアウト互換モード。ぼかし・曇り・背景輝度を調整でき、クリア / スタンダード / 曇りのプリセット付き。Mica はトップバーや入力欄など広い範囲をぼかすため、ストリーミング中は GPU を消費します。気になる場合は互換モードか「クリア」プリセットを。',\n 'glass.enable': 'マスタースイッチ',\n 'glass.mode': 'モード',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': '互換',\n 'glass.modeHint': 'Mica は浮遊するすりガラスカードに再構成。互換は原版レイアウトのまま素材だけガラスに(広範囲のぼかしなし=軽い)',\n 'glass.presets': 'プリセット',\n 'glass.presetClear': 'クリア',\n 'glass.presetStandard': 'スタンダード',\n 'glass.presetFrosted': '曇り',\n 'glass.blur': 'ぼかし',\n 'glass.frost': '曇り',\n 'glass.brightness': '背景の輝度',\n 'glass.brightnessHintDark': 'ダーク: 0 で純黒、50 でそのまま',\n 'glass.brightnessHintLight': 'ライト: 50 でそのまま、100 で純白',\n 'glass.reset': 'デフォルトに戻す',\n 'update.title': 'Catppuccin プラグインの更新を確認',\n 'update.description': 'npm 上の dsh-catppuccin 最新版を確認し、このインストールが最新かどうかを判断します。',\n 'update.helpLabel': '更新チェックについて',\n 'update.help': 'npm registry に本プラグインの最新版を問い合わせます。自動チェックを有効にすると起動時と6時間ごとに確認。チャンネルを beta にするとプレリリースも追跡します。',\n 'update.autoCheck': '更新を自動チェック',\n 'update.channel': 'チャンネル',\n 'update.channelLatest': '安定版',\n 'update.channelBeta': 'Beta',\n 'update.check': '更新を確認',\n 'update.checking': '確認中…',\n 'update.current': '現在のバージョン',\n 'update.upToDate': '最新です 🎉',\n 'update.available': '新しいバージョンがあります:',\n 'update.autoAvailable': '自動チェックで新しいバージョン:',\n 'update.commandHint': 'ターミナルで以下を実行してアップグレード(web をあなたの profile 名に変更):',\n 'update.commandHintDetected': 'profile「{profile}」を検出。ターミナルで以下を実行してアップグレード:',\n 'update.commandHintDesktop': 'DSH Desktop を検出。target profile「{profile}」、DSH ターミナルで以下を実行:',\n 'update.commandHintOfficialDesktop': '公式デスクトップ版(DeepSeek Harness クライアント)を検出: CLI からのアップグレード経路はありません——**プラグイン画面**で本プラグインを先に削除し、下のパッケージ名を「プラグインを追加」に貼り付けて再インストールしてください。',\n 'update.restartHint': 'アップグレード後、dsh web を再起動してください。',\n 'update.restartHintDesktop': 'アップグレード後、DSH Desktop を再起動してください。',\n 'update.copy': 'コマンドをコピー',\n 'update.copySpec': 'パッケージ名をコピー',\n 'update.copied': 'コピーしました ✓',\n 'update.failed': '確認に失敗しました。後で再試行してください。',\n 'update.retry': '再試行',\n 'update.retryHint': '{s} 秒後に自動再試行…',\n 'update.checkedAt': '確認時刻',\n 'update.localInstall': 'ローカルリンク/ソースインストールを検出しました。npm のアップグレードコマンドは使えないかもしれません。git pull か再ビルドを。',\n 'update.conflict': '別のウィンドウが設定を更新したため、ローカルの変更は保存されませんでした。',\n 'update.conflictDismiss': '閉じる',\n 'update.err.registry': 'npm registry に接続できません。ネットワークを確認して再試行してください。',\n 'update.err.http': 'npm registry が異常なステータスコードを返しました。',\n 'update.err.noTags': 'npm registry が利用可能なバージョンタグを返しませんでした。',\n 'update.err.invalid': 'npm registry が解析不能なデータを返しました。',\n 'update.err.networkLocal': 'プラグインのホストに接続できません。ネットワークを確認してページを更新してください。',\n 'update.err.networkUpstream': 'npm registry が一時的に利用できません(タイムアウト)。後で再試行してください。',\n 'links.title': 'フィードバックとサポート',\n 'links.issue': 'Catppuccin 外観プラグインの問題や提案がありますか?Issue を作成',\n 'links.star': 'この Catppuccin 外観プラグインが気に入ったら GitHub でスターを ⭐',\n}\n\n/** Korean dictionary. */\nexport const ko: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin 테마',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha 네 가지 배색, 한 번의 클릭으로 전환.',\n 'row.off': '시스템 팔로우',\n 'row.helpLabel': 'Catppuccin 테마 정보',\n 'row.help': 'Catppuccin 커뮤니티의 네 가지 배색: Latte(밝음), Frappé / Macchiato / Mocha(어두움). 선택 즉시 적용되고 저장됩니다.',\n 'row.shikiStyle': '코드 하이라이트',\n 'row.shikiDefault': '기본',\n 'row.shikiItalicComments': '부드러운 주석',\n 'row.overrides': '사용자 정의 오버라이드',\n 'row.overridesHint': '\"--dsw-* 변수: 값\" 형태로 개별 토큰을 덮어씁니다. 예: --dsw-static-blue-500: #89b4fa. 포커스를 벗어나면 적용, 빈 값은 삭제.',\n 'row.overridesEmpty': '아직 오버라이드가 없습니다. \"+ 추가\"로 만드세요.',\n 'row.overridesAdd': '추가',\n 'row.overridesRemove': '이 오버라이드 삭제',\n 'row.overridesKey': '토큰 이름',\n 'row.overridesValue': '토큰 값',\n 'flavor.latte.subtitle': '밝음',\n 'flavor.frappe.subtitle': '어두움',\n 'flavor.macchiato.subtitle': '어두움',\n 'flavor.mocha.subtitle': '어두움',\n 'glass.title': '글라스 질감',\n 'glass.description': '상단바·사이드바·입력창·통계줄·궤적 뷰에 프러스트드 글라스 효과, 원클릭 ON/OFF.',\n 'glass.helpLabel': '글라스 질감 정보',\n 'glass.help': 'Catppuccin 테마 위에 얹는 글라스 스킨: 떠 있는 카드(Mica) 또는 원본 레이아웃 호환 모드. 블러·프로스트·배경 밝기를 조절할 수 있고 클리어/스탠다드/프로스트 프리셋이 있습니다. Mica는 상단 바·입력창 등 넓은 영역을 흐리게 하므로 스트리밍 중 GPU를 더 씁니다. 부담되면 호환 모드나 「클리어」 프리셋을 쓰세요.',\n 'glass.enable': '마스터 스위치',\n 'glass.mode': '모드',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': '호환',\n 'glass.modeHint': 'Mica는 UI를 떠 있는 프러스트드 카드로 변경. 호환은 원본 레이아웃을 유지하고 재질만 글라스로 (넓은 영역 블러 없음 = 더 가벼움)',\n 'glass.presets': '프리셋',\n 'glass.presetClear': '클리어',\n 'glass.presetStandard': '스탠다드',\n 'glass.presetFrosted': '프로스트',\n 'glass.blur': '블러',\n 'glass.frost': '프로스트',\n 'glass.brightness': '배경 밝기',\n 'glass.brightnessHintDark': '다크 모드: 0이면 순수 검정, 50이면 그대로',\n 'glass.brightnessHintLight': '라이트 모드: 50이면 그대로, 100이면 순수 흰색',\n 'glass.reset': '기본값으로 되돌리기',\n 'update.title': 'Catppuccin 플러그인 업데이트 확인',\n 'update.description': 'npm의 최신 dsh-catppuccin 버전을 확인하고 현재 설치가 최신인지 판단합니다.',\n 'update.helpLabel': '업데이트 확인 정보',\n 'update.help': 'npm registry에서 이 플러그인의 최신 버전을 조회합니다. 자동 확인을 켜면 시작 시와 6시간마다 확인합니다. 채널을 beta로 하면 프리릴리스도 추적합니다.',\n 'update.autoCheck': '업데이트 자동 확인',\n 'update.channel': '채널',\n 'update.channelLatest': '안정판',\n 'update.channelBeta': 'Beta',\n 'update.check': '업데이트 확인',\n 'update.checking': '확인 중…',\n 'update.current': '현재 버전',\n 'update.upToDate': '최신 버전입니다 🎉',\n 'update.available': '새 버전 발견:',\n 'update.autoAvailable': '자동 확인으로 새 버전 발견:',\n 'update.commandHint': '터미널에서 다음을 실행해 업그레이드하세요 (web을 당신의 profile 이름으로 교체):',\n 'update.commandHintDetected': 'profile「{profile}」을 감지했습니다. 터미널에서 다음을 실행하세요:',\n 'update.commandHintDesktop': 'DSH Desktop 감지. 대상 profile「{profile}」, DSH 터미널에서 다음을 실행하세요:',\n 'update.commandHintOfficialDesktop': '공식 데스크톱 버전(DeepSeek Harness 클라이언트)을 감지했습니다: CLI 업그레이드 경로가 없습니다——**플러그인 화면**에서 이 플러그인을 먼저 삭제한 뒤 아래 패키지 이름을 「플러그인 추가」에 붙여 다시 설치하세요.',\n 'update.restartHint': '업그레이드 후 dsh web을 재시작하세요.',\n 'update.restartHintDesktop': '업그레이드 후 DSH Desktop을 재시작하세요.',\n 'update.copy': '명령 복사',\n 'update.copySpec': '패키지 이름 복사',\n 'update.copied': '복사됨 ✓',\n 'update.failed': '확인 실패. 잠시 후 다시 시도하세요.',\n 'update.retry': '다시 시도',\n 'update.retryHint': '{s}초 후 자동 재시도…',\n 'update.checkedAt': '확인 시각',\n 'update.localInstall': '로컬 링크/소스 설치를 감지했습니다. npm 업그레이드 명령이 맞지 않을 수 있으니 git pull 또는 재빌드를 사용하세요.',\n 'update.conflict': '다른 창에서 설정을 업데이트했습니다. 로컬 변경 사항은 저장되지 않았습니다.',\n 'update.conflictDismiss': '닫기',\n 'update.err.registry': 'npm registry에 연결할 수 없습니다. 네트워크를 확인하고 다시 시도하세요.',\n 'update.err.http': 'npm registry가 비정상 상태 코드를 반환했습니다.',\n 'update.err.noTags': 'npm registry가 사용 가능한 버전 태그를 반환하지 않았습니다.',\n 'update.err.invalid': 'npm registry가 해석할 수 없는 데이터를 반환했습니다.',\n 'update.err.networkLocal': '플러그인 호스트에 연결할 수 없습니다. 네트워크를 확인한 뒤 페이지를 새로고침하세요.',\n 'update.err.networkUpstream': 'npm registry를 일시적으로 사용할 수 없습니다(시간 초과). 잠시 후 다시 시도하세요.',\n 'links.title': '피드백 및 지원',\n 'links.issue': 'Catppuccin 테마 플러그인에 문제나 제안이 있나요? 이슈를 남겨 주세요',\n 'links.star': '이 Catppuccin 테마 플러그인이 마음에 드셨다면 GitHub에서 스타를 ⭐',\n}\n\n/** Spanish dictionary. */\nexport const es: Record<keyof typeof zh, string> = {\n 'row.title': 'Tema Catppuccin',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, a un clic.',\n 'row.off': 'Seguir al sistema',\n 'row.helpLabel': 'Acerca del tema Catppuccin',\n 'row.help': 'Cuatro paletas de la comunidad Catppuccin: Latte (claro), Frappé / Macchiato / Mocha (oscuro). Se aplican al instante y se guardan.',\n 'row.shikiStyle': 'Estilo de resaltado',\n 'row.shikiDefault': 'Predeterminado',\n 'row.shikiItalicComments': 'Comentarios suaves',\n 'row.overrides': 'Anulaciones personalizadas',\n 'row.overridesHint': 'Anula tokens individuales como \"variable --dsw-*: valor\", p. ej. --dsw-static-blue-500: #89b4fa. Se aplica al salir del campo; un valor vacío elimina la entrada.',\n 'row.overridesEmpty': 'Aún no hay anulaciones. Pulsa \"+ Añadir\" para crear una.',\n 'row.overridesAdd': 'Añadir',\n 'row.overridesRemove': 'Eliminar esta anulación',\n 'row.overridesKey': 'Nombre del token',\n 'row.overridesValue': 'Valor del token',\n 'flavor.latte.subtitle': 'Claro',\n 'flavor.frappe.subtitle': 'Oscuro',\n 'flavor.macchiato.subtitle': 'Oscuro',\n 'flavor.mocha.subtitle': 'Oscuro',\n 'glass.title': 'Vidrio esmerilado',\n 'glass.description': 'Efecto de vidrio esmerilado en barra superior, barra lateral, redactor, línea de estadísticas y vista de trayectoria: un clic para activarlo.',\n 'glass.helpLabel': 'Acerca del vidrio esmerilado',\n 'glass.help': 'Una piel de vidrio esmerilado sobre el tema Catppuccin: tarjetas flotantes (Mica) o el diseño original con material de vidrio (Compatibilidad). Desenfoque, escarcha y brillo del fondo ajustables, con preajustes Claro / Estándar / Escarchado. Mica desenfoca zonas grandes (barra superior, cuadro de texto), así que consume GPU mientras llega la respuesta: usa Compatibilidad o el preajuste Claro si te importa.',\n 'glass.enable': 'Interruptor general',\n 'glass.mode': 'Modo',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Compatibilidad',\n 'glass.modeHint': 'Mica convierte la interfaz en tarjetas flotantes esmeriladas; Compatibilidad mantiene el diseño original y solo cambia el material (sin desenfoque de zonas grandes: más ligero)',\n 'glass.presets': 'Preajustes',\n 'glass.presetClear': 'Claro',\n 'glass.presetStandard': 'Estándar',\n 'glass.presetFrosted': 'Escarchado',\n 'glass.blur': 'Desenfoque del vidrio',\n 'glass.frost': 'Escarcha',\n 'glass.brightness': 'Brillo del fondo',\n 'glass.brightnessHintDark': 'Modo oscuro: 0 atenúa a negro puro, 50 sin cambios',\n 'glass.brightnessHintLight': 'Modo claro: 50 sin cambios, 100 aclara hasta blanco puro',\n 'glass.reset': 'Restablecer valores',\n 'update.title': 'Comprobar actualizaciones del plugin Catppuccin',\n 'update.description': 'Comprueba en npm la última versión de dsh-catppuccin y si esta instalación está al día.',\n 'update.helpLabel': 'Acerca de la comprobación de actualizaciones',\n 'update.help': 'Consulta a npm registry la versión más reciente de este plugin. Con la comprobación automática activada, se consulta al inicio y cada 6 horas; el canal Beta también persigue prelanzamientos.',\n 'update.autoCheck': 'Comprobación automática',\n 'update.channel': 'Canal',\n 'update.channelLatest': 'Estable',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Comprobar actualizaciones',\n 'update.checking': 'Comprobando…',\n 'update.current': 'Versión actual',\n 'update.upToDate': 'Ya está actualizado 🎉',\n 'update.available': 'Nueva versión disponible:',\n 'update.autoAvailable': 'La comprobación automática encontró una versión nueva:',\n 'update.commandHint': 'Ejecuta esto en una terminal para actualizar (sustituye web por el nombre de tu profile):',\n 'update.commandHintDetected': 'Profile \"{profile}\" detectado: ejecuta esto en una terminal para actualizar:',\n 'update.commandHintDesktop': 'DSH Desktop detectado: profile objetivo \"{profile}\", ejecuta esto en la terminal de DSH:',\n 'update.commandHintOfficialDesktop': 'Se detectó la versión oficial de escritorio (cliente DeepSeek Harness): no tiene ruta de actualización por CLI; elimina este plugin en la página **Plugins** y pega el nombre del paquete de abajo en «Añadir plugin» para reinstalarlo.',\n 'update.restartHint': 'Reinicia dsh web tras la actualización.',\n 'update.restartHintDesktop': 'Reinicia DSH Desktop tras la actualización.',\n 'update.copy': 'Copiar comando',\n 'update.copySpec': 'Copiar nombre del paquete',\n 'update.copied': 'Copiado ✓',\n 'update.failed': 'Error al comprobar; inténtalo de nuevo más tarde.',\n 'update.retry': 'Reintentar',\n 'update.retryHint': 'Reintento automático en {s}s…',\n 'update.checkedAt': 'Comprobado a las',\n 'update.localInstall': 'Instalación local por enlace/código detectada: el comando npm puede no servir; usa git pull o reconstruye.',\n 'update.conflict': 'Otra ventana actualizó los ajustes: tus cambios locales no se guardaron.',\n 'update.conflictDismiss': 'Descartar',\n 'update.err.registry': 'No se pudo conectar con npm registry: revisa tu red e inténtalo de nuevo.',\n 'update.err.http': 'npm registry devolvió un código de estado inesperado.',\n 'update.err.noTags': 'npm registry no devolvió etiquetas de versión utilizables.',\n 'update.err.invalid': 'npm registry devolvió datos no analizables.',\n 'update.err.networkLocal': 'No se pudo conectar con el host del plugin: revisa tu red y recarga la página.',\n 'update.err.networkUpstream': 'npm registry no está disponible temporalmente (tiempo de espera agotado); inténtalo más tarde.',\n 'links.title': 'Comentarios y soporte',\n 'links.issue': '¿Un problema o una idea con el plugin de apariencia Catppuccin? Abre un issue',\n 'links.star': '¿Te gusta este plugin de apariencia Catppuccin? Dale una estrella en GitHub ⭐',\n}\n\n/** French dictionary. */\nexport const fr: Record<keyof typeof zh, string> = {\n 'row.title': 'Thème Catppuccin',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, en un clic.',\n 'row.off': 'Suivre le système',\n 'row.helpLabel': 'À propos du thème Catppuccin',\n 'row.help': 'Quatre palettes de la communauté Catppuccin : Latte (clair), Frappé / Macchiato / Mocha (sombre). Application immédiate et persistante.',\n 'row.shikiStyle': 'Style de coloration',\n 'row.shikiDefault': 'Par défaut',\n 'row.shikiItalicComments': 'Commentaires doux',\n 'row.overrides': 'Remplacements personnalisés',\n 'row.overridesHint': 'Remplace des jetons individuellement sous la forme « variable --dsw-*: valeur », ex. --dsw-static-blue-500: #89b4fa. Application à la sortie du champ ; une valeur vide supprime l\\'entrée.',\n 'row.overridesEmpty': 'Aucun remplacement pour l\\'instant. Cliquez sur « + Ajouter » pour en créer un.',\n 'row.overridesAdd': 'Ajouter',\n 'row.overridesRemove': 'Supprimer ce remplacement',\n 'row.overridesKey': 'Nom du jeton',\n 'row.overridesValue': 'Valeur du jeton',\n 'flavor.latte.subtitle': 'Clair',\n 'flavor.frappe.subtitle': 'Sombre',\n 'flavor.macchiato.subtitle': 'Sombre',\n 'flavor.mocha.subtitle': 'Sombre',\n 'glass.title': 'Verre dépoli',\n 'glass.description': 'Effet verre dépoli sur la barre du haut, la barre latérale, le rédacteur, la ligne de stats et la vue de trajectoire — un clic pour activer.',\n 'glass.helpLabel': 'À propos du verre dépoli',\n 'glass.help': 'Une peau en verre dépoli par-dessus le thème Catppuccin : cartes flottantes (Mica) ou mise en page d\\'origine avec un matériau verre (Compatibilité). Flou, givre et luminosité du fond réglables, avec les préréglages Clair / Standard / Givré. Mica floute de grandes zones (barre supérieure, champ de saisie) : cela consomme le GPU pendant la génération — préférez Compatibilité ou le préréglage Clair si c\\'est gênant.',\n 'glass.enable': 'Interrupteur principal',\n 'glass.mode': 'Mode',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Compatibilité',\n 'glass.modeHint': 'Mica transforme l\\'interface en cartes flottantes dépoli ; Compatibilité garde la mise en page d\\'origine et change seulement le matériau (pas de flou sur de grandes zones : plus léger)',\n 'glass.presets': 'Préréglages',\n 'glass.presetClear': 'Clair',\n 'glass.presetStandard': 'Standard',\n 'glass.presetFrosted': 'Givré',\n 'glass.blur': 'Flou du verre',\n 'glass.frost': 'Givre',\n 'glass.brightness': 'Luminosité du fond',\n 'glass.brightnessHintDark': 'Mode sombre : 0 atténue vers le noir pur, 50 inchangé',\n 'glass.brightnessHintLight': 'Mode clair : 50 inchangé, 100 éclaircit vers le blanc pur',\n 'glass.reset': 'Restaurer les valeurs',\n 'update.title': 'Vérifier les mises à jour du plugin Catppuccin',\n 'update.description': 'Interroge npm pour la dernière version de dsh-catppuccin et indique si cette installation est à jour.',\n 'update.helpLabel': 'À propos de la vérification des mises à jour',\n 'update.help': 'Interroge npm registry pour la dernière version de ce plugin. Avec la vérification automatique active, un contrôle a lieu au démarrage puis toutes les 6 heures ; le canal Beta suit aussi les préversions.',\n 'update.autoCheck': 'Vérification automatique',\n 'update.channel': 'Canal',\n 'update.channelLatest': 'Stable',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Vérifier les mises à jour',\n 'update.checking': 'Vérification…',\n 'update.current': 'Version actuelle',\n 'update.upToDate': 'À jour 🎉',\n 'update.available': 'Nouvelle version disponible :',\n 'update.autoAvailable': 'La vérification automatique a trouvé une nouvelle version :',\n 'update.commandHint': 'Exécutez ceci dans un terminal pour mettre à jour (remplacez web par le nom de votre profile) :',\n 'update.commandHintDetected': 'Profile « {profile} » détecté — exécutez ceci dans un terminal :',\n 'update.commandHintDesktop': 'DSH Desktop détecté — profile cible « {profile} », exécutez ceci dans le terminal DSH :',\n 'update.commandHintOfficialDesktop': 'Version bureau officielle détectée (client DeepSeek Harness) : aucune mise à jour en ligne de commande — supprimez ce plugin dans la page **Plugins**, puis collez le nom du paquet ci-dessous dans « Ajouter un plugin » pour le réinstaller.',\n 'update.restartHint': 'Redémarrez dsh web après la mise à jour.',\n 'update.restartHintDesktop': 'Redémarrez DSH Desktop après la mise à jour.',\n 'update.copy': 'Copier la commande',\n 'update.copySpec': 'Copier le nom du paquet',\n 'update.copied': 'Copié ✓',\n 'update.failed': 'Échec de la vérification — réessayez plus tard.',\n 'update.retry': 'Réessayer',\n 'update.retryHint': 'Nouvel essai automatique dans {s}s…',\n 'update.checkedAt': 'Vérifié à',\n 'update.localInstall': 'Installation locale par lien/code source détectée : la commande npm peut ne pas convenir ; utilisez git pull ou reconstruisez.',\n 'update.conflict': 'Une autre fenêtre a mis à jour les réglages — vos modifications locales n\\'ont pas été enregistrées.',\n 'update.conflictDismiss': 'Ignorer',\n 'update.err.registry': 'Impossible de joindre npm registry — vérifiez votre réseau et réessayez.',\n 'update.err.http': 'npm registry a renvoyé un code de statut inattendu.',\n 'update.err.noTags': 'npm registry n\\'a renvoyé aucune étiquette de version utile.',\n 'update.err.invalid': 'npm registry a renvoyé des données non analysables.',\n 'update.err.networkLocal': 'Impossible de joindre l\\'hôte du plugin — vérifiez votre réseau puis rechargez la page.',\n 'update.err.networkUpstream': 'npm registry est temporairement indisponible (délai dépassé) — réessayez plus tard.',\n 'links.title': 'Retours et support',\n 'links.issue': 'Un problème ou une idée pour le plugin d\\'apparence Catppuccin ? Ouvrez une issue',\n 'links.star': 'Vous aimez ce plugin d\\'apparence Catppuccin ? Laissez une Star sur GitHub ⭐',\n}\n\n/** German dictionary. */\nexport const de: Record<keyof typeof zh, string> = {\n 'row.title': 'Catppuccin-Design',\n 'row.description': 'Latte / Frappé / Macchiato / Mocha, mit einem Klick.',\n 'row.off': 'System folgen',\n 'row.helpLabel': 'Über das Catppuccin-Design',\n 'row.help': 'Vier Paletten der Catppuccin-Community: Latte (hell), Frappé / Macchiato / Mocha (dunkel). Wirkt sofort und wird gespeichert.',\n 'row.shikiStyle': 'Code-Hervorhebung',\n 'row.shikiDefault': 'Standard',\n 'row.shikiItalicComments': 'Sanfte Kommentare',\n 'row.overrides': 'Benutzerdefinierte Überschreibungen',\n 'row.overridesHint': 'Einzelne Tokens als „--dsw-*-Variable: Wert“ überschreiben, z. B. --dsw-static-blue-500: #89b4fa. Wirkt beim Verlassen des Feldes; ein leerer Wert löscht den Eintrag.',\n 'row.overridesEmpty': 'Noch keine Überschreibungen. Klicken Sie auf „+ Hinzufügen“, um eine anzulegen.',\n 'row.overridesAdd': 'Hinzufügen',\n 'row.overridesRemove': 'Diese Überschreibung entfernen',\n 'row.overridesKey': 'Token-Name',\n 'row.overridesValue': 'Token-Wert',\n 'flavor.latte.subtitle': 'Hell',\n 'flavor.frappe.subtitle': 'Dunkel',\n 'flavor.macchiato.subtitle': 'Dunkel',\n 'flavor.mocha.subtitle': 'Dunkel',\n 'glass.title': 'Glasmorphismus',\n 'glass.description': 'Milchglas-Effekt für obere Leiste, Seitenleiste, Eingabe, Statistikzeile und Trajektorienansicht – ein Klick an/aus.',\n 'glass.helpLabel': 'Über Glasmorphismus',\n 'glass.help': 'Eine Milchglas-Haut über dem Catppuccin-Design: schwebende Karten (Mica) oder das Original-Layout mit Glas-Material (Kompatibilität). Unschärfe, Frost und Hintergrundhelligkeit einstellbar, mit den Voreinstellungen Klar / Standard / Frostig. Mica verwischt große Flächen (Kopfleiste, Eingabefeld) und kostet daher GPU, während die Antwort streamt — nimm Kompatibilität oder die Voreinstellung Klar, wenn das stört.',\n 'glass.enable': 'Hauptschalter',\n 'glass.mode': 'Modus',\n 'glass.modeMica': 'Mica',\n 'glass.modeCompat': 'Kompatibilität',\n 'glass.modeHint': 'Mica verwandelt die Oberfläche in schwebende Milchglas-Karten; Kompatibilität behält das Original-Layout und tauscht nur das Material (keine großen Unschärfeflächen — die leichtere Option)',\n 'glass.presets': 'Voreinstellungen',\n 'glass.presetClear': 'Klar',\n 'glass.presetStandard': 'Standard',\n 'glass.presetFrosted': 'Frostig',\n 'glass.blur': 'Glas-Unschärfe',\n 'glass.frost': 'Frost',\n 'glass.brightness': 'Hintergrundhelligkeit',\n 'glass.brightnessHintDark': 'Dunkelmodus: 0 verdunkelt zu reinem Schwarz, 50 unverändert',\n 'glass.brightnessHintLight': 'Hellmodus: 50 unverändert, 100 hellt zu reinem Weiß auf',\n 'glass.reset': 'Standardwerte wiederherstellen',\n 'update.title': 'Catppuccin-Plugin-Updates prüfen',\n 'update.description': 'Prüft die neueste dsh-catppuccin-Version auf npm und ob diese Installation aktuell ist.',\n 'update.helpLabel': 'Über die Update-Prüfung',\n 'update.help': 'Fragt npm registry nach der neuesten Version dieses Plugins. Bei aktivierter automatischer Prüfung läuft ein Check beim Start und alle 6 Stunden; der Beta-Kanal verfolgt auch Vorabversionen.',\n 'update.autoCheck': 'Automatisch prüfen',\n 'update.channel': 'Kanal',\n 'update.channelLatest': 'Stabil',\n 'update.channelBeta': 'Beta',\n 'update.check': 'Auf Updates prüfen',\n 'update.checking': 'Prüfe…',\n 'update.current': 'Aktuelle Version',\n 'update.upToDate': 'Aktuell 🎉',\n 'update.available': 'Neue Version verfügbar:',\n 'update.autoAvailable': 'Automatische Prüfung fand eine neue Version:',\n 'update.commandHint': 'Führen Sie dies in einem Terminal aus (ersetzen Sie web durch Ihren Profile-Namen):',\n 'update.commandHintDetected': 'Profile „{profile}“ erkannt – führen Sie dies in einem Terminal aus:',\n 'update.commandHintDesktop': 'DSH Desktop erkannt – Ziel-Profile „{profile}“, führen Sie dies im DSH-Terminal aus:',\n 'update.commandHintOfficialDesktop': 'Offizielle Desktop-Version erkannt (DeepSeek Harness-Client): Es gibt keinen CLI-Upgradepfad – löschen Sie dieses Plugin auf der Seite **Plugins** und fügen Sie den Paketnamen unten in „Plugin hinzufügen“ ein, um es neu zu installieren.',\n 'update.restartHint': 'Starten Sie dsh web nach dem Update neu.',\n 'update.restartHintDesktop': 'Starten Sie DSH Desktop nach dem Update neu.',\n 'update.copy': 'Befehl kopieren',\n 'update.copySpec': 'Paketnamen kopieren',\n 'update.copied': 'Kopiert ✓',\n 'update.failed': 'Prüfung fehlgeschlagen – versuchen Sie es später erneut.',\n 'update.retry': 'Erneut versuchen',\n 'update.retryHint': 'Automatischer Versuch in {s}s…',\n 'update.checkedAt': 'Geprüft um',\n 'update.localInstall': 'Lokale Link-/Quellcode-Installation erkannt: Der npm-Befehl passt möglicherweise nicht; verwenden Sie git pull oder einen Neubuild.',\n 'update.conflict': 'Ein anderes Fenster hat die Einstellungen aktualisiert – Ihre lokalen Änderungen wurden nicht gespeichert.',\n 'update.conflictDismiss': 'Schließen',\n 'update.err.registry': 'npm registry nicht erreichbar – prüfen Sie Ihre Verbindung und versuchen Sie es erneut.',\n 'update.err.http': 'npm registry lieferte einen unerwarteten Statuscode.',\n 'update.err.noTags': 'npm registry lieferte keine brauchbaren Versions-Tags.',\n 'update.err.invalid': 'npm registry lieferte nicht analysierbare Daten.',\n 'update.err.networkLocal': 'Plugin-Host nicht erreichbar – prüfen Sie Ihre Verbindung und laden Sie die Seite neu.',\n 'update.err.networkUpstream': 'npm registry ist vorübergehend nicht verfügbar (Zeitüberschreitung) – versuchen Sie es später erneut.',\n 'links.title': 'Feedback & Support',\n 'links.issue': 'Problem oder Idee zum Catppuccin-Design-Plugin? Eröffnen Sie ein Issue',\n 'links.star': 'Gefällt Ihnen dieses Catppuccin-Design-Plugin? Geben Sie ihm einen Star auf GitHub ⭐',\n}\n\n/** Key union of the Catppuccin dictionaries. */\nexport type CatppuccinKey = keyof typeof zh","/**\n * AUTO-GENERATED by scripts/generate-palettes.mjs — do not edit by hand.\n * Catppuccin token tables for the DeepSeek Harness web GUI.\n * Source palette: https://github.com/catppuccin/catppuccin (palette.json v1.8.0).\n * // UPSTREAM_PIN: 639ed015397290b3745d163aafe02ffee4aa3f84\n * Each flavour carries a flat dictionary of every --dsw-static-*,\n * --dsw-alias-* and --dsw-specific-* token the official theme stylesheet\n * declares, plus the --dsw-* tokens outside those families (0.2.0's\n * --dsw-menu-surface-fill). Alias/specific entries keep their var() references\n * so the static overrides below flow through automatically; literal (non-var)\n * entries are remapped to Catppuccin colours — see aliasLiteralOverrides.\n */\nexport type CatppuccinFlavorId = 'latte' | 'frappe' | 'macchiato' | 'mocha'\nexport interface CatppuccinFlavorInfo {\n /** Theme id registered into ThemeRuntime. */\n themeId: string\n /** Base color scheme this flavour builds on. */\n colorScheme: 'light' | 'dark'\n /** Display label. */\n label: string\n /** Accent colour for the settings row swatch. */\n accent: string\n /** Token dictionary (--dsw-* names). */\n tokens: Record<string, string>\n}\n\nexport const CATPPUCCIN_LATTE: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-latte',\n colorScheme: 'light',\n label: 'Latte',\n accent: '#1e66f5',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #fe640b 20%, #eff1f5)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #fe640b 70%, #eff1f5)\",\n \"--dsw-static-amber-500\": \"#fe640b\",\n \"--dsw-static-amber-600\": \"#fe640b\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #fe640b 32%, #eff1f5)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #1e66f5 22%, #eff1f5)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #1e66f5 48%, #eff1f5)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #1e66f5 65%, #eff1f5)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-blue-500\": \"#1e66f5\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #1e66f5 8%, #eff1f5)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #1e66f5 12%, #eff1f5)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #1e66f5 16%, #eff1f5)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #1e66f5 50%, #eff1f5)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #1e66f5 30%, #4c4f69)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #1e66f5 26%, #eff1f5)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #1e66f5 22%, #eff1f5)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #1e66f5 34%, #eff1f5)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #1e66f5 48%, #eff1f5)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #1e66f5 65%, #eff1f5)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-deepseek-500\": \"#1e66f5\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #1e66f5 8%, #eff1f5)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #1e66f5 82%, #eff1f5)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #1e66f5 66%, #eff1f5)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #1e66f5 50%, #eff1f5)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #1e66f5 38%, #eff1f5)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #40a02b 18%, #eff1f5)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #40a02b 80%, #eff1f5)\",\n \"--dsw-static-green-500\": \"#40a02b\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #40a02b 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #40a02b 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #40a02b 30%, #eff1f5)\",\n \"--dsw-static-neutral-00\": \"#eff1f5\",\n \"--dsw-static-neutral-1000\": \"#4c4f69\",\n \"--dsw-static-neutral-100\": \"#bcc0cc\",\n \"--dsw-static-neutral-150\": \"#acb0be\",\n \"--dsw-static-neutral-200\": \"#9ca0b0\",\n \"--dsw-static-neutral-250\": \"#9ca0b0\",\n \"--dsw-static-neutral-300\": \"#8c8fa1\",\n \"--dsw-static-neutral-400\": \"#7c7f93\",\n \"--dsw-static-neutral-500\": \"#6c6f85\",\n \"--dsw-static-neutral-50\": \"#e6e9ef\",\n \"--dsw-static-neutral-550\": \"#6c6f85\",\n \"--dsw-static-neutral-600\": \"#5c5f77\",\n \"--dsw-static-neutral-700\": \"#5c5f77\",\n \"--dsw-static-neutral-800\": \"#4c4f69\",\n \"--dsw-static-neutral-850\": \"#4c4f69\",\n \"--dsw-static-neutral-900\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-00\": \"#eff1f5\",\n \"--dsw-static-neutral-bluish-1000\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-100\": \"#bcc0cc\",\n \"--dsw-static-neutral-bluish-150\": \"#acb0be\",\n \"--dsw-static-neutral-bluish-200\": \"#9ca0b0\",\n \"--dsw-static-neutral-bluish-300\": \"#8c8fa1\",\n \"--dsw-static-neutral-bluish-400\": \"#7c7f93\",\n \"--dsw-static-neutral-bluish-500\": \"#6c6f85\",\n \"--dsw-static-neutral-bluish-50\": \"#e6e9ef\",\n \"--dsw-static-neutral-bluish-600\": \"#5c5f77\",\n \"--dsw-static-neutral-bluish-60\": \"#e6e9ef\",\n \"--dsw-static-neutral-bluish-700\": \"#5c5f77\",\n \"--dsw-static-neutral-bluish-750\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-75\": \"#ccd0da\",\n \"--dsw-static-neutral-bluish-800\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-850\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-875\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-900\": \"#4c4f69\",\n \"--dsw-static-neutral-bluish-950\": \"#4c4f69\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #d20f39 20%, #eff1f5)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #d20f39 70%, #eff1f5)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #db5371 12%, transparent)\",\n \"--dsw-static-red-500\": \"#d20f39\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #d20f39 10%, #eff1f5)\",\n \"--dsw-static-red-600\": \"#d20f39\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #d20f39 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #d20f39 34%, #eff1f5)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.24)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.12)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(255, 255, 255, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(0, 0, 0, 0.04)\",\n \"--dsw-alias-border-inverted2\": \"rgba(0, 0, 0, 0)\",\n \"--dsw-alias-border-inverted\": \"rgba(0, 0, 0, 0)\",\n \"--dsw-alias-border-l1\": \"rgba(0, 0, 0, 0.04)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(0, 0, 0, 0.1)\",\n \"--dsw-alias-border-l2\": \"rgba(0, 0, 0, 0.1)\",\n \"--dsw-alias-border-l3\": \"rgba(0, 0, 0, 0.12)\",\n \"--dsw-alias-border-l4\": \"rgba(0, 0, 0, 0.16)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#1e66f5\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-500)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(38, 49, 72, 0.1)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(38, 49, 72, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(236, 19, 19, 0.05)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(38, 49, 72, 0.06)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-500) 70%, var(--dsw-static-blue-950))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-deepseek-500) 30%, var(--dsw-static-blue-950))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-blue-900)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-1000) 30%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-50)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-200)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-200)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-300)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-300)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-100)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a08)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-600-a08)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a08)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 4%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-600-a08)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 4%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-600)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-300)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-100)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-100)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-markdown-code-block)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-deepseek-200)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-deepseek-50)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-deepseek-100)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-60)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 58%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_FRAPPE: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-frappe',\n colorScheme: 'dark',\n label: 'Frappé',\n accent: '#8caaee',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #ef9f76 20%, #303446)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #ef9f76 70%, #303446)\",\n \"--dsw-static-amber-500\": \"#ef9f76\",\n \"--dsw-static-amber-600\": \"#ef9f76\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #ef9f76 18%, #232634)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #8caaee 24%, #303446)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #8caaee 50%, #303446)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #8caaee 66%, #303446)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-blue-500\": \"#8caaee\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #8caaee 10%, #303446)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #8caaee 14%, #303446)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #8caaee 18%, #303446)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #8caaee 18%, #232634)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #8caaee 14%, #232634)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #8caaee 10%, #232634)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #8caaee 24%, #303446)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #8caaee 36%, #303446)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #8caaee 50%, #303446)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #8caaee 66%, #303446)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-deepseek-500\": \"#8caaee\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #8caaee 10%, #303446)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #8caaee 84%, #303446)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #8caaee 68%, #303446)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #8caaee 18%, #232634)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #8caaee 14%, #232634)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #a6d189 18%, #303446)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #a6d189 80%, #303446)\",\n \"--dsw-static-green-500\": \"#a6d189\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #a6d189 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #a6d189 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #a6d189 18%, #232634)\",\n \"--dsw-static-neutral-00\": \"#c6d0f5\",\n \"--dsw-static-neutral-1000\": \"#232634\",\n \"--dsw-static-neutral-100\": \"#a5adce\",\n \"--dsw-static-neutral-150\": \"#a5adce\",\n \"--dsw-static-neutral-200\": \"#949cbb\",\n \"--dsw-static-neutral-250\": \"#949cbb\",\n \"--dsw-static-neutral-300\": \"#838ba7\",\n \"--dsw-static-neutral-400\": \"#737994\",\n \"--dsw-static-neutral-500\": \"#626880\",\n \"--dsw-static-neutral-50\": \"#c6d0f5\",\n \"--dsw-static-neutral-550\": \"#51576d\",\n \"--dsw-static-neutral-600\": \"#51576d\",\n \"--dsw-static-neutral-700\": \"#414559\",\n \"--dsw-static-neutral-800\": \"#414559\",\n \"--dsw-static-neutral-850\": \"#303446\",\n \"--dsw-static-neutral-900\": \"#292c3c\",\n \"--dsw-static-neutral-bluish-00\": \"#c6d0f5\",\n \"--dsw-static-neutral-bluish-1000\": \"#232634\",\n \"--dsw-static-neutral-bluish-100\": \"#a5adce\",\n \"--dsw-static-neutral-bluish-150\": \"#a5adce\",\n \"--dsw-static-neutral-bluish-200\": \"#949cbb\",\n \"--dsw-static-neutral-bluish-300\": \"#838ba7\",\n \"--dsw-static-neutral-bluish-400\": \"#737994\",\n \"--dsw-static-neutral-bluish-500\": \"#626880\",\n \"--dsw-static-neutral-bluish-50\": \"#c6d0f5\",\n \"--dsw-static-neutral-bluish-600\": \"#51576d\",\n \"--dsw-static-neutral-bluish-60\": \"#b5bfe2\",\n \"--dsw-static-neutral-bluish-700\": \"#414559\",\n \"--dsw-static-neutral-bluish-750\": \"#414559\",\n \"--dsw-static-neutral-bluish-75\": \"#b5bfe2\",\n \"--dsw-static-neutral-bluish-800\": \"#414559\",\n \"--dsw-static-neutral-bluish-850\": \"#303446\",\n \"--dsw-static-neutral-bluish-875\": \"#292c3c\",\n \"--dsw-static-neutral-bluish-900\": \"#292c3c\",\n \"--dsw-static-neutral-bluish-950\": \"#232634\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #e78284 20%, #303446)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #e78284 70%, #303446)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #b06b71 12%, transparent)\",\n \"--dsw-static-red-500\": \"#e78284\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #e78284 10%, #303446)\",\n \"--dsw-static-red-600\": \"#e78284\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #e78284 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #e78284 34%, #303446)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-875)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.5)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.2)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(39, 39, 48, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-850)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted2\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l1\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2\": \"rgba(255, 255, 255, 0.12)\",\n \"--dsw-alias-border-l3\": \"rgba(255, 255, 255, 0.16)\",\n \"--dsw-alias-border-l4\": \"rgba(255, 255, 255, 0.2)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#8caaee\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(255, 255, 255, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(255, 255, 255, 0.24)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(242, 90, 90, 0.15)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-450) 55%, var(--dsw-static-neutral-bluish-400))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-blue-300) 65%, var(--dsw-static-deepseek-400))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-00) 45%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-alias-label-primary-dimmed)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-800)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-700)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-550)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-800)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-900)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-900)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-active)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 45%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_MACCHIATO: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-macchiato',\n colorScheme: 'dark',\n label: 'Macchiato',\n accent: '#8aadf4',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #f5a97f 20%, #24273a)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #f5a97f 70%, #24273a)\",\n \"--dsw-static-amber-500\": \"#f5a97f\",\n \"--dsw-static-amber-600\": \"#f5a97f\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #f5a97f 18%, #181926)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #8aadf4 24%, #24273a)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #8aadf4 50%, #24273a)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #8aadf4 66%, #24273a)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-blue-500\": \"#8aadf4\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #8aadf4 10%, #24273a)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #8aadf4 14%, #24273a)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #8aadf4 18%, #24273a)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #8aadf4 18%, #181926)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #8aadf4 14%, #181926)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #8aadf4 10%, #181926)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #8aadf4 24%, #24273a)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #8aadf4 36%, #24273a)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #8aadf4 50%, #24273a)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #8aadf4 66%, #24273a)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-deepseek-500\": \"#8aadf4\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #8aadf4 10%, #24273a)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #8aadf4 84%, #24273a)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #8aadf4 68%, #24273a)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #8aadf4 18%, #181926)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #8aadf4 14%, #181926)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #a6da95 18%, #24273a)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #a6da95 80%, #24273a)\",\n \"--dsw-static-green-500\": \"#a6da95\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #a6da95 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #a6da95 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #a6da95 18%, #181926)\",\n \"--dsw-static-neutral-00\": \"#cad3f5\",\n \"--dsw-static-neutral-1000\": \"#181926\",\n \"--dsw-static-neutral-100\": \"#a5adcb\",\n \"--dsw-static-neutral-150\": \"#a5adcb\",\n \"--dsw-static-neutral-200\": \"#939ab7\",\n \"--dsw-static-neutral-250\": \"#939ab7\",\n \"--dsw-static-neutral-300\": \"#8087a2\",\n \"--dsw-static-neutral-400\": \"#6e738d\",\n \"--dsw-static-neutral-500\": \"#5b6078\",\n \"--dsw-static-neutral-50\": \"#cad3f5\",\n \"--dsw-static-neutral-550\": \"#494d64\",\n \"--dsw-static-neutral-600\": \"#494d64\",\n \"--dsw-static-neutral-700\": \"#363a4f\",\n \"--dsw-static-neutral-800\": \"#363a4f\",\n \"--dsw-static-neutral-850\": \"#24273a\",\n \"--dsw-static-neutral-900\": \"#1e2030\",\n \"--dsw-static-neutral-bluish-00\": \"#cad3f5\",\n \"--dsw-static-neutral-bluish-1000\": \"#181926\",\n \"--dsw-static-neutral-bluish-100\": \"#a5adcb\",\n \"--dsw-static-neutral-bluish-150\": \"#a5adcb\",\n \"--dsw-static-neutral-bluish-200\": \"#939ab7\",\n \"--dsw-static-neutral-bluish-300\": \"#8087a2\",\n \"--dsw-static-neutral-bluish-400\": \"#6e738d\",\n \"--dsw-static-neutral-bluish-500\": \"#5b6078\",\n \"--dsw-static-neutral-bluish-50\": \"#cad3f5\",\n \"--dsw-static-neutral-bluish-600\": \"#494d64\",\n \"--dsw-static-neutral-bluish-60\": \"#b8c0e0\",\n \"--dsw-static-neutral-bluish-700\": \"#363a4f\",\n \"--dsw-static-neutral-bluish-750\": \"#363a4f\",\n \"--dsw-static-neutral-bluish-75\": \"#b8c0e0\",\n \"--dsw-static-neutral-bluish-800\": \"#363a4f\",\n \"--dsw-static-neutral-bluish-850\": \"#24273a\",\n \"--dsw-static-neutral-bluish-875\": \"#1e2030\",\n \"--dsw-static-neutral-bluish-900\": \"#1e2030\",\n \"--dsw-static-neutral-bluish-950\": \"#181926\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #ed8796 20%, #24273a)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #ed8796 70%, #24273a)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #b16a7a 12%, transparent)\",\n \"--dsw-static-red-500\": \"#ed8796\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #ed8796 10%, #24273a)\",\n \"--dsw-static-red-600\": \"#ed8796\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #ed8796 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #ed8796 34%, #24273a)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-875)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.5)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.2)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(39, 39, 48, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-850)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted2\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l1\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2\": \"rgba(255, 255, 255, 0.12)\",\n \"--dsw-alias-border-l3\": \"rgba(255, 255, 255, 0.16)\",\n \"--dsw-alias-border-l4\": \"rgba(255, 255, 255, 0.2)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#8aadf4\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(255, 255, 255, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(255, 255, 255, 0.24)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(242, 90, 90, 0.15)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-450) 55%, var(--dsw-static-neutral-bluish-400))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-blue-300) 65%, var(--dsw-static-deepseek-400))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-00) 45%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-alias-label-primary-dimmed)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-800)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-700)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-550)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-800)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-900)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-900)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-active)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 45%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_MOCHA: CatppuccinFlavorInfo = {\n themeId: 'catppuccin-mocha',\n colorScheme: 'dark',\n label: 'Mocha',\n accent: '#89b4fa',\n tokens: {\n \"--dsw-static-amber-100\": \"color-mix(in srgb, #fab387 20%, #1e1e2e)\",\n \"--dsw-static-amber-400\": \"color-mix(in srgb, #fab387 70%, #1e1e2e)\",\n \"--dsw-static-amber-500\": \"#fab387\",\n \"--dsw-static-amber-600\": \"#fab387\",\n \"--dsw-static-amber-900\": \"color-mix(in srgb, #fab387 18%, #11111b)\",\n \"--dsw-static-blue-100\": \"color-mix(in srgb, #89b4fa 24%, #1e1e2e)\",\n \"--dsw-static-blue-300\": \"color-mix(in srgb, #89b4fa 50%, #1e1e2e)\",\n \"--dsw-static-blue-400\": \"color-mix(in srgb, #89b4fa 66%, #1e1e2e)\",\n \"--dsw-static-blue-450\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-blue-500\": \"#89b4fa\",\n \"--dsw-static-blue-50\": \"color-mix(in srgb, #89b4fa 10%, #1e1e2e)\",\n \"--dsw-static-blue-50p\": \"color-mix(in srgb, #89b4fa 14%, #1e1e2e)\",\n \"--dsw-static-blue-600\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-blue-75\": \"color-mix(in srgb, #89b4fa 18%, #1e1e2e)\",\n \"--dsw-static-blue-800\": \"color-mix(in srgb, #89b4fa 18%, #11111b)\",\n \"--dsw-static-blue-900\": \"color-mix(in srgb, #89b4fa 14%, #11111b)\",\n \"--dsw-static-blue-950\": \"color-mix(in srgb, #89b4fa 10%, #11111b)\",\n \"--dsw-static-deepseek-100\": \"color-mix(in srgb, #89b4fa 24%, #1e1e2e)\",\n \"--dsw-static-deepseek-200\": \"color-mix(in srgb, #89b4fa 36%, #1e1e2e)\",\n \"--dsw-static-deepseek-300\": \"color-mix(in srgb, #89b4fa 50%, #1e1e2e)\",\n \"--dsw-static-deepseek-400\": \"color-mix(in srgb, #89b4fa 66%, #1e1e2e)\",\n \"--dsw-static-deepseek-450\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-deepseek-500\": \"#89b4fa\",\n \"--dsw-static-deepseek-50\": \"color-mix(in srgb, #89b4fa 10%, #1e1e2e)\",\n \"--dsw-static-deepseek-600\": \"color-mix(in srgb, #89b4fa 84%, #1e1e2e)\",\n \"--dsw-static-deepseek-700-delete\": \"color-mix(in srgb, #89b4fa 68%, #1e1e2e)\",\n \"--dsw-static-deepseek-800\": \"color-mix(in srgb, #89b4fa 18%, #11111b)\",\n \"--dsw-static-deepseek-900\": \"color-mix(in srgb, #89b4fa 14%, #11111b)\",\n \"--dsw-static-green-100\": \"color-mix(in srgb, #a6e3a1 18%, #1e1e2e)\",\n \"--dsw-static-green-400\": \"color-mix(in srgb, #a6e3a1 80%, #1e1e2e)\",\n \"--dsw-static-green-500\": \"#a6e3a1\",\n \"--dsw-static-green-500-a08\": \"color-mix(in srgb, #a6e3a1 8%, transparent)\",\n \"--dsw-static-green-500-a12\": \"color-mix(in srgb, #a6e3a1 12%, transparent)\",\n \"--dsw-static-green-900\": \"color-mix(in srgb, #a6e3a1 18%, #11111b)\",\n \"--dsw-static-neutral-00\": \"#cdd6f4\",\n \"--dsw-static-neutral-1000\": \"#11111b\",\n \"--dsw-static-neutral-100\": \"#a6adc8\",\n \"--dsw-static-neutral-150\": \"#a6adc8\",\n \"--dsw-static-neutral-200\": \"#9399b2\",\n \"--dsw-static-neutral-250\": \"#9399b2\",\n \"--dsw-static-neutral-300\": \"#7f849c\",\n \"--dsw-static-neutral-400\": \"#6c7086\",\n \"--dsw-static-neutral-500\": \"#585b70\",\n \"--dsw-static-neutral-50\": \"#cdd6f4\",\n \"--dsw-static-neutral-550\": \"#45475a\",\n \"--dsw-static-neutral-600\": \"#45475a\",\n \"--dsw-static-neutral-700\": \"#313244\",\n \"--dsw-static-neutral-800\": \"#313244\",\n \"--dsw-static-neutral-850\": \"#1e1e2e\",\n \"--dsw-static-neutral-900\": \"#181825\",\n \"--dsw-static-neutral-bluish-00\": \"#cdd6f4\",\n \"--dsw-static-neutral-bluish-1000\": \"#11111b\",\n \"--dsw-static-neutral-bluish-100\": \"#a6adc8\",\n \"--dsw-static-neutral-bluish-150\": \"#a6adc8\",\n \"--dsw-static-neutral-bluish-200\": \"#9399b2\",\n \"--dsw-static-neutral-bluish-300\": \"#7f849c\",\n \"--dsw-static-neutral-bluish-400\": \"#6c7086\",\n \"--dsw-static-neutral-bluish-500\": \"#585b70\",\n \"--dsw-static-neutral-bluish-50\": \"#cdd6f4\",\n \"--dsw-static-neutral-bluish-600\": \"#45475a\",\n \"--dsw-static-neutral-bluish-60\": \"#bac2de\",\n \"--dsw-static-neutral-bluish-700\": \"#313244\",\n \"--dsw-static-neutral-bluish-750\": \"#313244\",\n \"--dsw-static-neutral-bluish-75\": \"#bac2de\",\n \"--dsw-static-neutral-bluish-800\": \"#313244\",\n \"--dsw-static-neutral-bluish-850\": \"#1e1e2e\",\n \"--dsw-static-neutral-bluish-875\": \"#181825\",\n \"--dsw-static-neutral-bluish-900\": \"#181825\",\n \"--dsw-static-neutral-bluish-950\": \"#11111b\",\n \"--dsw-static-red-100\": \"color-mix(in srgb, #f38ba8 20%, #1e1e2e)\",\n \"--dsw-static-red-400\": \"color-mix(in srgb, #f38ba8 70%, #1e1e2e)\",\n \"--dsw-static-red-400-a12\": \"color-mix(in srgb, #b36a83 12%, transparent)\",\n \"--dsw-static-red-500\": \"#f38ba8\",\n \"--dsw-static-red-50\": \"color-mix(in srgb, #f38ba8 10%, #1e1e2e)\",\n \"--dsw-static-red-600\": \"#f38ba8\",\n \"--dsw-static-red-600-a08\": \"color-mix(in srgb, #f38ba8 8%, transparent)\",\n \"--dsw-static-red-900\": \"color-mix(in srgb, #f38ba8 34%, #1e1e2e)\",\n \"--dsw-alias-bg-base\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-preview\": \"var(--dsw-static-neutral-bluish-950)\",\n \"--dsw-alias-bg-document-selection\": \"color-mix(in srgb, var(--dsw-static-blue-500) 40%, transparent)\",\n \"--dsw-alias-label-document-preview\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-bg-layer-1\": \"var(--dsw-static-neutral-bluish-875)\",\n \"--dsw-alias-bg-layer-2\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-bg-layer-3\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-mask-1\": \"rgba(0, 0, 0, 0.5)\",\n \"--dsw-alias-bg-mask-2\": \"rgba(0, 0, 0, 0.2)\",\n \"--dsw-alias-bg-mask-3\": \"rgba(0, 0, 0, 0.48)\",\n \"--dsw-alias-bg-mask-photo\": \"rgba(0, 0, 0, 0.88)\",\n \"--dsw-alias-bg-mask-drop\": \"rgba(39, 39, 48, 0.7)\",\n \"--dsw-alias-bg-module-platform\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-bg-multi-select\": \"var(--dsw-static-neutral-850)\",\n \"--dsw-alias-bg-overlay\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-bg-skeleton\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted2\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-border-inverted\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l1\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2-darkmode-thin\": \"rgba(255, 255, 255, 0.06)\",\n \"--dsw-alias-border-l2\": \"rgba(255, 255, 255, 0.12)\",\n \"--dsw-alias-border-l3\": \"rgba(255, 255, 255, 0.16)\",\n \"--dsw-alias-border-l4\": \"rgba(255, 255, 255, 0.2)\",\n \"--dsw-alias-brand-primary-invert\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-primary-new-colorprimary-new-color\": \"#89b4fa\",\n \"--dsw-alias-brand-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-brand-text\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-contrast-fill\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-button-elevated-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-floating-fill\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-button-floating-hover\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-button-ghost-active-border\": \"var(--dsw-static-neutral-bluish-600)\",\n \"--dsw-alias-button-ghost-active-fill\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-ghost-active-hover\": \"var(--dsw-static-neutral-bluish-700)\",\n \"--dsw-alias-button-info-fill\": \"var(--dsw-static-deepseek-400)\",\n \"--dsw-alias-button-info-hover\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-button-primary-dimmed\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-button-primary-fill\": \"var(--dsw-alias-brand-primary)\",\n \"--dsw-alias-button-primary-hover\": \"var(--dsw-static-neutral-bluish-100)\",\n \"--dsw-alias-button-tool-bar-fill-invisible\": \"rgba(31, 31, 31, 0.36)\",\n \"--dsw-alias-button-tool-bar-fill\": \"rgba(84, 85, 87, 0.5)\",\n \"--dsw-alias-button-tool-bar-hover\": \"rgba(84, 85, 87, 0.6)\",\n \"--dsw-alias-interactive-bg-active\": \"rgba(255, 255, 255, 0.14)\",\n \"--dsw-alias-interactive-bg-hover-accent\": \"rgba(255, 255, 255, 0.24)\",\n \"--dsw-alias-interactive-bg-hover-danger\": \"rgba(242, 90, 90, 0.15)\",\n \"--dsw-alias-interactive-bg-hover-solid\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-interactive-bg-hover\": \"rgba(255, 255, 255, 0.08)\",\n \"--dsw-alias-label-caption\": \"var(--dsw-static-neutral-bluish-300)\",\n \"--dsw-alias-label-deep-diving\": \"color-mix(in srgb, var(--dsw-static-deepseek-450) 55%, var(--dsw-static-neutral-bluish-400))\",\n \"--dsw-alias-label-deep-diving-shimmer\": \"color-mix(in srgb, var(--dsw-static-blue-300) 65%, var(--dsw-static-deepseek-400))\",\n \"--dsw-alias-label-dimmed\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-label-primary-bluish\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-primary-dimmed\": \"var(--dsw-static-neutral-bluish-75)\",\n \"--dsw-alias-label-primary-foreground\": \"var(--dsw-static-neutral-bluish-1000)\",\n \"--dsw-alias-label-primary-inverted\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-label-primary\": \"var(--dsw-static-neutral-bluish-50)\",\n \"--dsw-alias-label-secondary\": \"var(--dsw-static-neutral-bluish-150)\",\n \"--dsw-alias-label-shimmer\": \"color-mix(in srgb, var(--dsw-static-neutral-00) 45%, transparent)\",\n \"--dsw-alias-label-tertiary\": \"var(--dsw-static-neutral-bluish-200)\",\n \"--dsw-alias-menu-icon\": \"var(--dsw-alias-label-primary-dimmed)\",\n \"--dsw-alias-link\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-markdown-citation\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-block-banner\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-code-block\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-code-segment-selected\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-alias-markdown-code-segment-unselected\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-alias-markdown-inline-code\": \"var(--dsw-static-neutral-800)\",\n \"--dsw-alias-markdown-placeholder\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-markdown-tag\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-alias-scrollbar-bg-l1\": \"var(--dsw-static-neutral-700)\",\n \"--dsw-alias-scrollbar-bg-l2\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l1\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-scrollbar-hover-l2\": \"var(--dsw-static-neutral-550)\",\n \"--dsw-alias-state-business-primary\": \"var(--dsw-static-deepseek-500)\",\n \"--dsw-alias-state-business-tertiary\": \"var(--dsw-static-deepseek-800)\",\n \"--dsw-alias-code-diff-added\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-code-diff-deleted\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-added-bg\": \"var(--dsw-static-green-500-a12)\",\n \"--dsw-alias-file-diff-added-gutter\": \"color-mix(in srgb, var(--dsw-static-green-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-added-marker\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-file-diff-deleted-bg\": \"var(--dsw-static-red-400-a12)\",\n \"--dsw-alias-file-diff-deleted-gutter\": \"color-mix(in srgb, var(--dsw-static-red-500) 6%, transparent)\",\n \"--dsw-alias-file-diff-deleted-marker\": \"var(--dsw-static-red-500)\",\n \"--dsw-alias-state-error-primary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-error-secondary\": \"var(--dsw-static-red-400)\",\n \"--dsw-alias-state-idle-primary\": \"var(--dsw-static-neutral-600)\",\n \"--dsw-alias-state-success-primary\": \"var(--dsw-static-green-500)\",\n \"--dsw-alias-state-success-secondary\": \"var(--dsw-static-green-400)\",\n \"--dsw-alias-state-success-tertiary\": \"var(--dsw-static-green-900)\",\n \"--dsw-alias-state-warn-label\": \"var(--dsw-static-amber-600)\",\n \"--dsw-alias-state-warn-primary\": \"var(--dsw-static-amber-500)\",\n \"--dsw-alias-state-warn-secondary\": \"var(--dsw-static-amber-400)\",\n \"--dsw-alias-state-warn-tertiary\": \"var(--dsw-static-amber-900)\",\n \"--dsw-alias-switch-thumb\": \"var(--dsw-static-neutral-bluish-400)\",\n \"--dsw-alias-toast-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-toast-label\": \"var(--dsw-static-neutral-bluish-00)\",\n \"--dsw-alias-turn-trigger-bg\": \"var(--dsw-alias-interactive-bg-hover)\",\n \"--dsw-alias-turn-trigger-bg-hover\": \"var(--dsw-alias-interactive-bg-active)\",\n \"--dsw-alias-tooltip-bg\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-alias-tooltip-key-bg\": \"color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%)\",\n \"--dsw-alias-menu-group-header-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 94%, transparent)\",\n \"--dsw-specific-bubble-highlight\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-bubble\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-input-major\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-login-input\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-menu\": \"var(--dsw-menu-surface-fill)\",\n \"--dsw-specific-selector\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-fill\": \"var(--dsw-static-neutral-bluish-900)\",\n \"--dsw-specific-sidebar-nav-item-active-accent\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-specific-sidebar-nav-item-active\": \"var(--dsw-static-neutral-bluish-750)\",\n \"--dsw-specific-sidebar-nav-item-hover\": \"var(--dsw-static-neutral-bluish-850)\",\n \"--dsw-specific-tip\": \"var(--dsw-static-neutral-bluish-800)\",\n \"--dsw-menu-surface-fill\": \"color-mix(in srgb, var(--dsw-alias-bg-layer-3) 45%, transparent)\",\n },\n}\n\nexport const CATPPUCCIN_FLAVORS: readonly CatppuccinFlavorInfo[] = [\n CATPPUCCIN_LATTE,\n CATPPUCCIN_FRAPPE,\n CATPPUCCIN_MACCHIATO,\n CATPPUCCIN_MOCHA,\n]\n","/**\n * Catppuccin syntax-highlighting token overrides for Shiki.\n *\n * DSH's default shiki.css (shipped by @deepseek-ai/dsh-client-ui-theme) defines\n * its own hard-coded syntax colours that are not Catppuccin. This module\n * supplies the canonical Catppuccin palette colours (sourced from the official\n * Shiki themes shipped by @shikijs/themes) for each of the four flavours, so\n * code blocks inside the DSH GUI match the Catppuccin project's syntax\n * highlighting.\n *\n * The foreground and background tokens are kept as var() references into the\n * plugin's own --dsw-* overrides (foreground -> label-primary, background ->\n * markdown-code-block), so they automatically track the active flavour. Every\n * other token is a literal hex from the Catppuccin palette.\n *\n * Styles (item M): the table is two-dimensional `SHIKI_TOKENS[flavor][style]`.\n * DSH's shiki.css only consumes the --shiki-* variables as colours (no style\n * attributes ride them — the highlighter owns font styles), so the\n * `italic-comments` variant is expressed as the comment colour hierarchy\n * difference it CAN carry: comments step down to the flavour's `subtext0`\n * (softer, clearly secondary) instead of `overlay2`. If a future DSH ships a\n * style-token layer, the variant should switch to font-style there instead.\n */\n\nimport type { CatppuccinFlavorId } from './palettes.ts'\nimport type { ShikiStyle } from '../state.ts'\n\n/** Shiki token names as defined by DSH's shiki.css. */\nexport type ShikiTokenName =\n | '--shiki-foreground'\n | '--shiki-background'\n | '--shiki-token-constant'\n | '--shiki-token-string'\n | '--shiki-token-comment'\n | '--shiki-token-keyword'\n | '--shiki-token-parameter'\n | '--shiki-token-function'\n | '--shiki-token-string-expression'\n | '--shiki-token-punctuation'\n | '--shiki-token-link'\n\n/** Per-flavour shiki token dictionary. */\nexport type ShikiTokens = Record<ShikiTokenName, string>\n\n/**\n * Canonical Catppuccin syntax colours per flavour.\n *\n * Colour → token mapping (from the official @shikijs/themes Catppuccin themes):\n * foreground → text\n * constant → peach\n * string → green\n * comment → overlay2\n * keyword → mauve\n * parameter → maroon\n * function → blue\n * string-expr → green (same as string)\n * punctuation → overlay2\n * link → blue (same as function)\n *\n * Background and foreground use var() references so they flow through the\n * flavour's --dsw-* overrides; the rest are literal hex.\n */\n\nconst BASE: Record<CatppuccinFlavorId, ShikiTokens> = {\n latte: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#fe640b', // peach\n '--shiki-token-string': '#40a02b', // green\n '--shiki-token-comment': '#7c7f93', // overlay2\n '--shiki-token-keyword': '#8839ef', // mauve\n '--shiki-token-parameter': '#e64553', // maroon\n '--shiki-token-function': '#1e66f5', // blue\n '--shiki-token-string-expression': '#40a02b', // green\n '--shiki-token-punctuation': '#7c7f93', // overlay2\n '--shiki-token-link': '#1e66f5', // blue\n },\n\n frappe: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#ef9f76', // peach\n '--shiki-token-string': '#a6d189', // green\n '--shiki-token-comment': '#949cbb', // overlay2\n '--shiki-token-keyword': '#ca9ee6', // mauve\n '--shiki-token-parameter': '#ea999c', // maroon\n '--shiki-token-function': '#8caaee', // blue\n '--shiki-token-string-expression': '#a6d189', // green\n '--shiki-token-punctuation': '#949cbb', // overlay2\n '--shiki-token-link': '#8caaee', // blue\n },\n\n macchiato: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#f5a97f', // peach\n '--shiki-token-string': '#a6da95', // green\n '--shiki-token-comment': '#939ab7', // overlay2\n '--shiki-token-keyword': '#c6a0f6', // mauve\n '--shiki-token-parameter': '#ee99a0', // maroon\n '--shiki-token-function': '#8aadf4', // blue\n '--shiki-token-string-expression': '#a6da95', // green\n '--shiki-token-punctuation': '#939ab7', // overlay2\n '--shiki-token-link': '#8aadf4', // blue\n },\n\n mocha: {\n '--shiki-foreground': 'var(--dsw-alias-label-primary)',\n '--shiki-background': 'var(--dsw-alias-markdown-code-block)',\n '--shiki-token-constant': '#fab387', // peach\n '--shiki-token-string': '#a6e3a1', // green\n '--shiki-token-comment': '#9399b2', // overlay2\n '--shiki-token-keyword': '#cba6f7', // mauve\n '--shiki-token-parameter': '#eba0ac', // maroon\n '--shiki-token-function': '#89b4fa', // blue\n '--shiki-token-string-expression': '#a6e3a1', // green\n '--shiki-token-punctuation': '#9399b2', // overlay2\n '--shiki-token-link': '#89b4fa', // blue\n },\n}\n\n/** Official Catppuccin `subtext0` per flavour — the comment colour of the\n * `italic-comments` variant (a step softer than `overlay2`, so comments\n * read clearly as secondary). */\nconst SUBTEXT0: Record<CatppuccinFlavorId, string> = {\n latte: '#6c6f85',\n frappe: '#a5adce',\n macchiato: '#a5adcb',\n mocha: '#a6adc8',\n}\n\n/** Re-point the comment token of a base dictionary. */\nfunction withComment(tokens: ShikiTokens, comment: string): ShikiTokens {\n return { ...tokens, '--shiki-token-comment': comment }\n}\n\n/** Per-flavour × per-style shiki token dictionaries. */\nexport const SHIKI_TOKENS: Record<CatppuccinFlavorId, Record<ShikiStyle, ShikiTokens>> = {\n latte: {\n default: BASE.latte,\n 'italic-comments': withComment(BASE.latte, SUBTEXT0.latte),\n },\n frappe: {\n default: BASE.frappe,\n 'italic-comments': withComment(BASE.frappe, SUBTEXT0.frappe),\n },\n macchiato: {\n default: BASE.macchiato,\n 'italic-comments': withComment(BASE.macchiato, SUBTEXT0.macchiato),\n },\n mocha: {\n default: BASE.mocha,\n 'italic-comments': withComment(BASE.mocha, SUBTEXT0.mocha),\n },\n}","/**\n * Shared contract of the update-check feature — consumed by both halves:\n * the Host registers an exact webServer route answering this JSON payload,\n * and the Client settings row fetches that same-origin route and renders it.\n * This module is dependency-free so both bundles inline it.\n */\nimport { compareVersions, parseVersion } from './versions.ts'\nimport type { UpdateChannel } from './state.ts'\n// Type-only (erased at build time): `update-check.ts` stays dependency-free for\n// both bundles while the payload can still name the host kind.\nimport type { ShellKind } from './profile-detect.ts'\n\nexport type { UpdateChannel } from './state.ts'\nexport type { ShellKind } from './profile-detect.ts'\n\n/** The plugin's own npm name (the registry lookup key). */\nexport const PACKAGE_NAME = '@nonamelego/dsh-catppuccin'\n\n/**\n * npm registry abbreviated packument endpoint (the `install-v1` document).\n * The `latest` endpoint alone is not enough: this project ships prereleases\n * under the `beta` dist-tag while `latest` stays on the last stable, so the\n * check reads `dist-tags` to serve both channels.\n */\nexport const REGISTRY_PACKUMENT_URL =\n `https://registry.npmjs.org/${PACKAGE_NAME.replace('/', '%2F')}`\n\n/** Host route the Client row fetches (exact match, same origin). */\nexport const UPDATE_ROUTE_PATH = '/catppuccin/check-update'\n\n/** Network budget for the Host's registry lookup. */\nexport const UPDATE_FETCH_TIMEOUT_MS = 8000\n\n/** Budget for the CLIENT half's same-origin fetch of {@link UPDATE_ROUTE_PATH}\n * (R3, 2026-10-10 review). The Host's own registry lookup is capped at\n * {@link UPDATE_FETCH_TIMEOUT_MS}, so this only ever bites when the host\n * process itself stopped answering — without it a wedged host leaves the\n * settings row stuck in its `checking` phase, where the disabled check button\n * makes a retry impossible. Comfortably larger than the host budget so a\n * slow-but-alive registry lookup is never cut off client-side. */\nexport const UPDATE_CHECK_CLIENT_TIMEOUT_MS = 15_000\n\n/** The `dist-tags` object of an npm packument. */\nexport interface DistTags {\n latest?: string\n beta?: string\n}\n\n/** The newest release a given install should chase, and on which channel. */\nexport interface NewestRelease {\n version: string\n channel: UpdateChannel\n}\n\n/**\n * The copyable CLI upgrade command for one channel (`dsh plugin` is a thin\n * pnpm forwarder). The profile name comes from the Host's runtime probe\n * (`src/profile-detect.ts`), never hard-coded, so the command works on any\n * deployment out of the box.\n *\n * ⚠️ **只适用于 `web` 与 `community-desktop`**(社区壳的应用内 DSH 终端里有效)。\n * 官方 Electron 壳的用户没有可达的终端入口(`resources/runtime/cli/bin/dsh.cmd`\n * 在代码上允许 `manageDesktopProfile: true`,但官方壳 UI 不提供终端),那条路改用\n * {@link pluginSpecFor} + 应用内「插件」页重装。\n * @param channel - the dist-tag to chase.\n * @param profile - the DSH profile name to target.\n */\nexport function updateCommandFor(channel: UpdateChannel, profile: string): string {\n return `dsh plugin --profile ${profile} add ${PACKAGE_NAME}@${channel}`\n}\n\n/**\n * The value to paste into a plugin manager's \"add plugin\" field — the shape the\n * official Electron shell's Plugins page accepts. Its 升级 path is\n * 「先删除、再重新安装同一个包名」, so the spec (not a CLI command) is the\n * copyable artefact there.\n * @param channel - the dist-tag to chase.\n */\nexport function pluginSpecFor(channel: UpdateChannel): string {\n return `${PACKAGE_NAME}@${channel}`\n}\n\n/**\n * Pick the newest release worth reporting for the given install:\n * - with NO channel preference: a stable install chases only `latest` (never\n * downgrades onto a beta), while a prerelease install (e.g. a\n * `beta`-tagged version) also chases `beta` — so beta users see newer\n * betas, and a stable release that outranks their prerelease promotes\n * them via `@latest`;\n * - an explicit `beta` preference (the settings row's prerelease pick)\n * chases `beta` even from a stable install — beta testers opt in without\n * changing their install; the newest of the two tags still wins, so a\n * newer stable promotes them back onto `@latest`;\n * - an explicit `latest` preference pins the check to the stable tag —\n * never a beta, even from a prerelease install.\n * @param current - the installed version.\n * @param tags - the registry's dist-tags.\n * @param preferredChannel - optional persisted channel preference (item I).\n * @returns the newest candidate and its channel, or null when nothing applies.\n */\nexport function selectNewest(current: string, tags: DistTags, preferredChannel?: UpdateChannel): NewestRelease | null {\n const candidates: NewestRelease[] = []\n if (tags.latest !== undefined) candidates.push({ version: tags.latest, channel: 'latest' })\n if (preferredChannel === 'beta') {\n // Beta chase, opt-in: follow the beta tag even from a stable install.\n if (tags.beta !== undefined) candidates.push({ version: tags.beta, channel: 'beta' })\n } else if (preferredChannel === undefined) {\n // No preference: prerelease installs chase beta on top of latest.\n const parsed = parseVersion(current)\n if (tags.beta !== undefined && parsed !== null && parsed.prerelease.length > 0) {\n candidates.push({ version: tags.beta, channel: 'beta' })\n }\n }\n // preferredChannel === 'latest': candidates hold the stable tag only.\n if (candidates.length === 0) return null\n let best = candidates[0]\n for (const candidate of candidates.slice(1)) {\n if (compareVersions(best.version, candidate.version) < 0) best = candidate\n }\n return best\n}\n\n/** Stable machine-readable outcome code (borrowed from the plugin-update\n * error-code discipline of dsh-vision-toolkit): the Client maps it to copy\n * instead of sniffing human text. `network.*` splits the old catch-all\n * `network` (item U): `network.local` means the browser→Host hop failed\n * (host unreachable / DNS — \"check your network\"), `network.upstream` means\n * the Host reached the registry but the lookup timed out (\"npm is\n * temporarily unavailable\"). */\nexport type UpdateErrorCode =\n | 'ok'\n | 'network.local' // the same-origin fetch itself failed (client side)\n | 'network.upstream' // the Host's registry fetch timed out\n | 'registry-unreachable' // npm registry could not be reached (fetch threw)\n | 'registry-http' // registry answered with a non-2xx status\n | 'no-dist-tags' // registry returned no usable dist-tags\n | 'invalid-response' // registry response could not be parsed\n\n/** How this package is installed inside the probed DSH profile. */\nexport type InstallSource = 'registry' | 'link' | 'file' | 'git' | 'unknown'\n\n/** Runtime that answered the check — drives the copy (command hint / restart). */\nexport type UpdateEnv = 'desktop' | 'web'\n\n/**\n * JSON payload of the update check. `ok: false` carries a human-readable\n * `error` plus a stable `code`; `ok: true` carries the comparison result.\n * The Host owns the semver comparison, the channel selection, and the\n * profile probe (single source of truth), so the Client never parses\n * versions or guesses the profile name itself.\n */\nexport interface UpdateCheckPayload {\n /** Whether the registry lookup succeeded. */\n ok: boolean\n /** Installed version (from this package's own manifest). */\n current?: string\n /** Newest release worth chasing (`latest`, plus `beta` for prerelease installs). */\n latest?: string\n /** `latest` is strictly newer than `current`. */\n outdated?: boolean\n /** The dist-tag the newest release came from. */\n channel?: UpdateChannel\n /** Copyable CLI upgrade command (present when outdated). Only on `web` and\n * `community-desktop` — the official shell has no reachable CLI path. */\n updateCommand?: string\n /** `pkg@tag` spec for the Plugins page's \"add plugin\" field. Present instead\n * of {@link updateCommand} on the official desktop shell. */\n updateSpec?: string\n /** Which host answered the check (drives the copy). */\n shell?: ShellKind\n /** DSH profile name the upgrade command targets (probed, not guessed). */\n profile?: string\n /** Whether the profile probe actually found the install (false = fallback). */\n profileDetected?: boolean\n /** Runtime that answered: DSH Desktop vs standard dsh web (drives copy). */\n env?: UpdateEnv\n /** How the package is installed in that profile (drives copy). */\n installSource?: InstallSource\n /** ISO timestamp of the check (registry lookup moment). */\n checkedAt?: string\n /** Stable outcome code (see {@link UpdateErrorCode}). */\n code?: UpdateErrorCode\n /** Failure detail (only when `ok` is false). */\n error?: string\n}\n","/**\n * Fault-tolerant registration for the plugin's boot-critical wiring.\n *\n * Client and Host share one failure shape: an entry whose `apply()` throws is\n * marked `failed`, the assembly aborts the whole boot (`web boot: N entries\n * did not activate`), and the official desktop's crash rescue then runs\n * `disableAllPlugins()` — taking EVERY third-party plugin down with it. A peer\n * plugin already owning what we are about to register is the realistic\n * trigger (language packs and their BCP 47 ids — issue #23; a duplicate\n * install and its route / slot / theme ids), and the right answer to\n * \"someone else already did this\" is to skip OUR copy — never to fail the\n * boot. Full evidence chain and the per-call-site audit live in\n * `docs/issue-23-registration-tolerance.md`.\n *\n * Known \"already owned\" shapes are skipped quietly — the peer's registration\n * stands, matching `dsh-locale-pack`'s own tolerance. Anything else is logged\n * and skipped too: no registration in this plugin is worth the user's whole\n * plugin set. (To restore fail-fast for a class of errors, `throw error` in\n * the warn branch — every call site routes through here on purpose.)\n */\n\n/** The \"another party already owns this\" messages the runtimes throw, checked\n * against the 0.2.0-rc.2 sources (table in the doc's §6):\n * - `locale \"ja\" is already registered` (dsh-client-locale addLanguage)\n * - `locale namespace \"…\" already has locale \"…\"` (dsh-client-locale register)\n * - `theme \"…\" is already registered` (dsh-client-ui-theme register)\n * - `list slot \"…\" already has an entry with id \"…\"` (dsh-client-ui-slots)\n * - `webserver: duplicate exact route \"…\"` (dsh-host-webserver register) */\nconst ALREADY_OWNED = /already (?:registered|has locale|has an entry)|duplicate .*route/u\n\n/**\n * Run one registration call, degrading any failure to a no-op disposer.\n * @param run - the registration call, returning its disposer (if any).\n * @returns the real disposer, or a no-op when the registration was skipped.\n */\nexport function tolerantRegistration(run: () => (() => void) | void): () => void {\n try {\n return run() ?? (() => {})\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n if (!ALREADY_OWNED.test(message)) {\n console.warn(`[dsh-catppuccin] registration skipped — ${message}`)\n }\n return () => {}\n }\n}\n","/**\n * Browser half of the durable Catppuccin state — an adapter over BOTH shapes\n * of the OFFICIAL settings seam, replacing the pre-0.5.0 `/catppuccin/state`\n * route wrapper.\n *\n * The seam changed shape in DSH 0.1.7-alpha.1 (issue #15) and both shapes are\n * in the wild (`latest` = 0.1.5-rc.3 on the old one, `next` = 0.1.7-rc.1 on\n * the new one), so this module binds whichever the host serves:\n *\n * - `ctx.configForms` (>= 0.1.7-alpha.1): the plugin's volatile `Config`\n * projected into a form keyed by the PROFILE ENTRY id, addressed through\n * `configForms.get(CATPPUCCIN_ENTRY_ID)`.\n * - `ctx.settingsScope` (<= 0.1.6-alpha.2): a namespace the Host half\n * registered, bound with `settingsScope.bind({ namespace })`.\n *\n * The two are not alike at the type level, but their SNAPSHOTS are\n * field-for-field identical (`status / value / base / user / revision /\n * writable / mode`), so one {@link DurableScope} interface covers both. Their\n * three behavioural differences are confined INSIDE the channel objects and\n * are deliberately not reachable by callers:\n *\n * 1. \"no user layer yet\" — the new form's `user` is the profile patch's\n * `override`, which defaults to `{}` (so `!== undefined` never fires\n * there); the legacy document omits the field entirely when it holds no\n * such section. → {@link DurableScope.hasUserLayer}.\n * 2. the write fence — the new controller takes an OPTIONAL\n * `expectedRevision` and reports a refusal as `false`; the legacy one has\n * no fence parameter at all and reports refusal as a SILENT resolve. Both\n * therefore resolve the fence themselves (`pendingRevision ??\n * snapshot.revision` on the new one) unless a caller supplies one, and\n * {@link persistStateToScope} deliberately supplies NONE — see the note\n * there. The only fence this module could offer is the revision a debounced\n * burst STARTED from, and a write of our own that lands inside the burst\n * moves the document past it; forwarding that older base makes the Host\n * refuse a write that must succeed, which the caller then reads as \"another\n * window changed the document\" and answers by reverting the user's newest\n * change (the fast-switching half of the 2026-10-01 report). Deciding the\n * fence stays the channel's job, exactly as before — the configForms\n * channel still forwards one when a staged editor supplies it.\n * → {@link DurableScope.write}.\n * 3. the refusal signal — only the new channel can report `refused`; the\n * legacy one cannot, which is why the read-side revision guard in\n * {@link persistStateToScope} must stay in place for BOTH channels.\n *\n * Every failure is still non-fatal: the plugin keeps working from browser\n * localStorage alone (the in-browser cache), losing only cross-restart\n * durability on profiles where the settings transport is absent or\n * process-local.\n */\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\n// Type-only: pulls the configForms Context merge and the form contract.\nimport type { ConfigForm, ConfigFormSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n CATPPUCCIN_ENTRY_ID,\n CATPPUCCIN_SETTINGS_NS,\n hasUserLayerSection,\n settingsSectionFromState,\n settingsSectionsEqual,\n stateFromSettingsSection,\n type CatppuccinSettingsSection,\n type CatppuccinState,\n} from '../state.ts'\n\n/** Client-side sync state of one settings namespace — the SHARED shape of\n * both seams (`ConfigFormSnapshot` on 0.1.7+, the scope snapshot before it;\n * the fields agree one for one, which is what makes the adapter possible). */\nexport interface DurableSnapshot<T> {\n /** `loading` until the first accepted section, `ready` while one stands,\n * `unavailable` when the namespace is not exposed to this client or the\n * connection keeps preferences process-local (memory mode). */\n status: 'loading' | 'ready' | 'unavailable'\n /** Last accepted schema-resolved section. */\n value: T | undefined\n /** Composition layer the Host resolved {@link value} over. */\n base: unknown\n /** Raw user layer as stored, when one exists. */\n user: unknown\n /** Revision fencing the next write. */\n revision: number | undefined\n /** Whether the Host document accepts writes; memory mode never does. */\n writable: boolean\n /** `host` syncs with the Host document; `memory` keeps a remote browser\n * process-local. */\n mode: 'host' | 'memory'\n}\n\n/** How one write ended. `refused` is only observable on the new channel. */\nexport type WriteOutcome = 'accepted' | 'refused' | 'failed'\n\n/** One settings channel: everything the two seams disagree about lives here. */\nexport interface DurableScope<T> {\n /** Which seam answered — diagnostics and test assertions only. */\n readonly kind: 'configForms' | 'settingsScope' | 'none'\n getSnapshot(): DurableSnapshot<T>\n subscribe(listener: () => void): () => void\n /** Whether the durable store already holds a user layer. The predicate is\n * per-channel on purpose (see difference 1 in the module header). */\n hasUserLayer(snapshot: DurableSnapshot<T>): boolean\n /** Issue one atomic write. Whether {@link baseRevision} becomes the Host's\n * fence is the channel's decision, never the caller's (difference 2).\n * `baseRevision` is for STAGED editors — upstream's contract is \"the revision\n * read before editing\", so a conflict preserves the draft. The debounced\n * whole-state write-back in {@link persistStateToScope} passes none on\n * purpose: its base is the pre-burst revision, not an edit-start revision. */\n write(ops: readonly SettingsPathOpView[], baseRevision?: number | undefined): Promise<WriteOutcome>\n}\n\n/** The snapshot an unbound scope reports: the pre-0.5.0 \"transport absent\"\n * degradation, where localStorage is the only store. */\nconst UNBOUND_SNAPSHOT: DurableSnapshot<never> = {\n status: 'unavailable',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'memory',\n}\n\n/** Whether the scope is usable for durable persistence: the document is\n * resolved (`ready`) and the Host persistence is active (`host`). A `memory`\n * scope (non-loopback pages / absent transport) or a not-yet-ready one is\n * NOT usable — the caller keeps localStorage as the only store. */\nexport function isScopeUsable(snapshot: DurableSnapshot<unknown>): boolean {\n return snapshot.status === 'ready' && snapshot.mode === 'host'\n}\n\n/** The local state contract (with the synthetic `version`) for a usable\n * scope snapshot; `null` while the section is not resolved. */\nexport function durableStateFromSnapshot(\n snapshot: DurableSnapshot<CatppuccinSettingsSection>,\n): CatppuccinState | null {\n if (!isScopeUsable(snapshot) || snapshot.value === undefined) return null\n return stateFromSettingsSection(snapshot.value)\n}\n\n/** The NEW seam's channel (DSH >= 0.1.7-alpha.1). */\nfunction configFormsScope(\n form: ConfigForm<CatppuccinSettingsSection>,\n): DurableScope<CatppuccinSettingsSection> {\n return {\n kind: 'configForms',\n getSnapshot: () => form.getSnapshot() as ConfigFormSnapshot<CatppuccinSettingsSection>,\n subscribe: (listener) => form.subscribe(listener),\n // The form's `user` is the profile patch's `override`, which the Host\n // defaults to `{}` — so an EMPTY OBJECT is what \"no user layer yet\" looks\n // like here, and it must not be mistaken for a real user layer.\n hasUserLayer: (snapshot) => hasUserLayerSection(snapshot.user),\n write: async (ops, baseRevision) => {\n try {\n // The returned boolean is the only refusal signal any seam gives us;\n // a transport failure rejects instead. `baseRevision` is forwarded\n // only when a caller supplies one (staged editors) — the debounced\n // write-back passes none and lets the controller fence with its own\n // `pendingRevision ?? snapshot.revision`, which is strictly fresher.\n return await form.mutate(ops, baseRevision) ? 'accepted' : 'refused'\n } catch {\n return 'failed'\n }\n },\n }\n}\n\n/**\n * The LEGACY seam's surface (DSH <= 0.1.6-alpha.2). Declared structurally\n * because 0.1.7 removed it from the published types while this plugin still\n * has to run on hosts that only have it, and reaching for `any` would hide a\n * real shape change.\n */\ninterface LegacyScope<T> {\n getSnapshot(): DurableSnapshot<T>\n subscribe(listener: () => void): () => void\n /** Note the absent `expectedRevision`: the legacy controller resolves the\n * fence itself (`pendingRevision ?? snapshot.revision`). */\n mutate(ops: readonly SettingsPathOpView[]): Promise<void>\n}\ninterface LegacyScopeBinder {\n bind<T>(spec: { namespace: string }): LegacyScope<T>\n}\n\n/** The LEGACY seam's channel (DSH <= 0.1.6-alpha.2). */\nfunction legacyScope(scope: LegacyScope<CatppuccinSettingsSection>): DurableScope<CatppuccinSettingsSection> {\n return {\n kind: 'settingsScope',\n getSnapshot: () => scope.getSnapshot(),\n subscribe: (listener) => scope.subscribe(listener),\n // The legacy document maps over the namespaces it has a section for, so\n // \"no user layer\" is an ABSENT field — the predicate 0.5.x shipped.\n hasUserLayer: (snapshot) => snapshot.user !== undefined,\n write: async (ops) => {\n try {\n // NO baseRevision on purpose: the legacy controller resolves the fence\n // itself and therefore retries with the newer revision. Forwarding our\n // older base would make a write that succeeds today fail — and that\n // failure is unobservable (the controller resolves it silently), so we\n // would not even notice.\n await scope.mutate(ops)\n return 'accepted'\n } catch {\n return 'failed'\n }\n },\n }\n}\n\n/**\n * Bind whichever settings channel this host serves, late and without blocking.\n *\n * Both bindings ride OPTIONAL injections: a service the deployment never\n * provides simply never fires its callback (it does not hold the plugin\n * back), and the two names cannot both be live in one host — 0.1.7-alpha.1\n * removed `settingsScope` from the service set, and 0.1.6 and earlier know\n * nothing of `configForms`. Until one binds, the scope reports the unbound\n * snapshot and every write short-circuits, which is exactly the\n * \"settings transport unavailable\" degradation the rows already handle.\n * @param ctx - client root context.\n * @returns the scope facade, bound for the lifetime of the caller's fiber.\n */\nexport function createDurableScope(ctx: Context): DurableScope<CatppuccinSettingsSection> {\n let current: DurableScope<CatppuccinSettingsSection> | undefined\n let offBound: (() => void) | undefined\n const listeners = new Set<() => void>()\n const notify = (): void => {\n for (const listener of [...listeners]) listener()\n }\n const attach = (next: DurableScope<CatppuccinSettingsSection> | undefined): void => {\n if (next === current) return\n offBound?.()\n current = next\n offBound = next?.subscribe(notify)\n // Re-run hydration/adoption: the durable state may only become readable\n // once a late-arriving service publishes its first snapshot.\n notify()\n }\n\n ctx.inject(['configForms'], (formsCtx) => {\n attach(configFormsScope(formsCtx.configForms.get<CatppuccinSettingsSection>(CATPPUCCIN_ENTRY_ID)))\n return () => { attach(undefined) }\n })\n ctx.inject(['settingsScope'], (legacyCtx) => {\n // `settingsScope` is not part of the 0.1.7 Context merge (the service is\n // gone there), so the legacy lookup is narrowed explicitly.\n const binder = (legacyCtx as unknown as { settingsScope?: LegacyScopeBinder }).settingsScope\n if (binder !== undefined) {\n attach(legacyScope(binder.bind<CatppuccinSettingsSection>({ namespace: CATPPUCCIN_SETTINGS_NS })))\n }\n return () => { attach(undefined) }\n })\n\n return {\n get kind() { return current?.kind ?? 'none' },\n getSnapshot: () => current?.getSnapshot()\n ?? UNBOUND_SNAPSHOT as DurableSnapshot<CatppuccinSettingsSection>,\n subscribe: (listener) => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n // Never reached while unbound: the caller bails out in\n // `durableStateFromSnapshot` before asking.\n hasUserLayer: (snapshot) => current?.hasUserLayer(snapshot) ?? false,\n write: async (ops, baseRevision) => current?.write(ops, baseRevision) ?? 'failed',\n }\n}\n\n/** One atomic mutation covering the whole local state (revision-fenced).\n * Writing every field keeps the section self-contained — a partial write\n * could otherwise leave a knob stuck on a stale override after a document\n * edit elsewhere. */\nfunction stateToMutateOps(state: CatppuccinState): SettingsPathOpView[] {\n const section = settingsSectionFromState(state)\n return [\n { op: 'set', path: ['flavor'], value: section.flavor },\n { op: 'set', path: ['glass', 'enabled'], value: section.glass.enabled },\n { op: 'set', path: ['glass', 'mode'], value: section.glass.mode },\n { op: 'set', path: ['glass', 'blur'], value: section.glass.blur },\n { op: 'set', path: ['glass', 'frost'], value: section.glass.frost },\n { op: 'set', path: ['glass', 'brightness'], value: section.glass.brightness },\n { op: 'set', path: ['autoCheck'], value: section.autoCheck },\n { op: 'set', path: ['updateChannel'], value: section.updateChannel },\n { op: 'set', path: ['overrides'], value: section.overrides },\n { op: 'set', path: ['shikiStyle'], value: section.shikiStyle },\n ]\n}\n\n/** Outcome of one durable persist attempt (item C/X). */\nexport type PersistOutcome =\n /** The mutation was issued (the Host may still fence-stall it later). */\n | 'written'\n /** The local state already equals the document — nothing to write. */\n | 'noop'\n /** The document moved past the revision the local state was derived from:\n * the local change is a stale write-back and was NOT written — the\n * remote (newer) state wins and the caller should adopt it + notify. */\n | 'stale'\n /** The write failed (transport error / rejected mutation). */\n | 'error'\n\n/**\n * Read-side consistency guard for the durable persist (items C/X).\n *\n * The WRITE side belongs to the channel — no optimistic locking is re-built\n * here — but the persist path deliberately does NOT hand it a fence: the base\n * below is the revision the local state was derived from (captured at SCHEDULE\n * time), which is the right input for the READ-side guard and the wrong input\n * for a write fence. A write of ours that lands inside the debounce window (or\n * is still in flight when the flush runs) moves the document past that base\n * while our mirror has not caught up, so fencing the next write with it makes\n * the Host refuse a write that must succeed; the refusal is then reported as\n * `stale`, and the caller adopts the remote state — silently reverting the\n * user's newest change. That is the 2026-10-01 \"switching the mica/compat mode\n * quickly sometimes fails\" report: two mode switches ~300ms apart, the second\n * one reverted.\n *\n * What a fence cannot see is a STALE LOCAL VIEW: tab A reads an old\n * localStorage value, the user changes flavour, and the debounced flush writes\n * that old-based state over tab B's already-committed newer choice. That is\n * what the guard below is for, and it is also the ONLY conflict detector the\n * legacy seam can offer — that seam resolves a refused write silently, so\n * without it a concurrent edit would be lost without a trace.\n *\n * The guard compares the revision the local state was derived from\n * (`baseRevision`, captured at schedule time) with the snapshot revision at\n * flush time:\n * - equal → the document did not move while we were debouncing → write.\n * - moved, and the remote section equals our own last written section →\n * the movement is our own write's echo, safe to write the newer change.\n * - moved otherwise → an external edit landed mid-debounce; the local\n * change is stale, so it is abandoned and `stale` is returned so the\n * caller can adopt the remote state and surface the conflict.\n * Also returns `noop` when the local state already equals the document\n * (the normal echo back of our own committed writes; previously this wrote\n * a redundant identical mutation).\n */\nexport async function persistStateToScope(\n scope: DurableScope<CatppuccinSettingsSection>,\n state: CatppuccinState,\n options: {\n /** Snapshot revision the local state was derived from (captured at\n * schedule time). Omit to skip the read-side guard entirely. */\n baseRevision?: number | undefined\n /** Section of the last successfully issued write (our own echo\n * fingerprint — revision movement matching it is not a conflict). */\n lastWrittenSection?: CatppuccinSettingsSection | undefined\n } = {},\n): Promise<PersistOutcome> {\n const snapshot = scope.getSnapshot()\n if (!isScopeUsable(snapshot)) return 'error'\n const remote = durableStateFromSnapshot(snapshot)\n const localSection = settingsSectionFromState(state)\n if (remote !== null && settingsSectionsEqual(settingsSectionFromState(remote), localSection)) {\n return 'noop'\n }\n const { baseRevision, lastWrittenSection } = options\n if (baseRevision !== undefined && snapshot.revision !== undefined && snapshot.revision !== baseRevision) {\n const ourOwnEcho = lastWrittenSection !== undefined\n && remote !== null\n && settingsSectionsEqual(settingsSectionFromState(remote), lastWrittenSection)\n if (!ourOwnEcho) return 'stale'\n }\n // No fence: the channel resolves `pendingRevision ?? snapshot.revision` when\n // the write actually goes out, which is both fresher than our captured base\n // and aware of our own superseded/in-flight writes (difference 2 in the\n // module header). The Host still validates it against the document, so an\n // external edit the mirror has not seen yet is still refused.\n const outcome = await scope.write(stateToMutateOps(state))\n if (outcome === 'accepted') return 'written'\n // A refusal means the Host's document moved past what this state was derived\n // from — the same condition the read-side guard above reports. The channel\n // has already re-read the Host state, so the caller can adopt it and tell\n // the row about the conflict.\n if (outcome === 'refused') return 'stale'\n return 'error'\n}\n\nlet pendingTimer: number | undefined\nlet pendingWrite: (() => void) | undefined\n\n/**\n * Debounced trailing persist: after a burst of changes (a slider drag emits a\n * stream of snapshot updates) the write happens once, a short beat after the\n * last change. Pass an accessor so the state snapshot is taken at flush time,\n * never stale.\n */\nexport function scheduleDurablePersist(write: () => void, delayMs = 300): void {\n if (pendingTimer !== undefined) window.clearTimeout(pendingTimer)\n pendingWrite = write\n pendingTimer = window.setTimeout(() => {\n pendingTimer = undefined\n const run = pendingWrite\n pendingWrite = undefined\n if (run !== undefined) void Promise.resolve().then(run).catch(() => { /* best-effort */ })\n }, delayMs)\n}\n\n/** Drop any queued persist (plugin unload / page teardown). */\nexport function cancelDurablePersist(): void {\n if (pendingTimer !== undefined) window.clearTimeout(pendingTimer)\n pendingTimer = undefined\n pendingWrite = undefined\n}\n\n/**\n * Capture-once holder for the revision a debounced write is based on (audit\n * F2, 2026-09-22).\n *\n * The read-side guard in {@link persistStateToScope} only means anything if\n * `baseRevision` is the revision the LOCAL state was derived from — i.e.\n * sampled when the change was SCHEDULED. Reading it inside the flush instead\n * made the comparison a tautology: the flush and the guard's own\n * `scope.getSnapshot()` run in the same synchronous block, so the two\n * revisions are always equal and `'stale'` is unreachable. The effect was a\n * silently lost read-side protection: with two windows open, an external edit\n * landing inside the 300 ms debounce window was overwritten by the stale local\n * state and the conflict banner never appeared.\n *\n * `capture` keeps the FIRST revision of a burst (`??=`, not assignment): a\n * slider drag emits several changes, and the local state each of them is based\n * on is still the one that was current when the burst started. `take` clears\n * the slot as it reads, so the next burst starts fresh — including when the\n * flush bails out (unusable scope), where the value must not leak forward.\n */\nexport function createBaseRevisionTracker(): {\n /** Sample the base revision once per burst (later calls in the same burst are no-ops). */\n capture: (read: () => number | undefined) => void\n /** Consume the captured revision (undefined when the burst never captured one). */\n take: () => number | undefined\n} {\n let pending: number | undefined\n return {\n capture(read) {\n if (pending === undefined) pending = read()\n },\n take() {\n const value = pending\n pending = undefined\n return value\n },\n }\n}\n","/**\n * Catppuccin themes for the DeepSeek Harness web GUI — browser half.\n *\n * Registers the four Catppuccin flavours (Latte light / Frappé, Macchiato,\n * Mocha dark) into the official ThemeRuntime, so they become selectable\n * themes whose --dsw-* token overrides fully remap the UI palette. The\n * official Appearance row persists only the built-in light/dark/system\n * preferences, so this plugin also owns a settings row (\"Catppuccin\") that\n * lists the four flavours; selecting one switches the theme and persists the\n * flavour.\n *\n * Persistence is two-tier since 0.5.0. The choice lives in two stores:\n * - localStorage keys (`dsh.catppuccin.*`) — the in-browser cache: instant\n * restore at boot, the cross-tab `storage` event bus, and the fallback\n * when the settings transport is unavailable;\n * - the official settings seam (registered/declared by the Host half in\n * `src/index.ts`) — the source of truth, bound here through\n * `createDurableScope`, which adapts whichever seam the host serves\n * (`ctx.settingsScope` up to 0.1.6-alpha.2, `ctx.configForms` from\n * 0.1.7-alpha.1 — see `src/client/state-sync.ts`). It exists because\n * localStorage is per-browser and per-origin while the DSH home is the\n * machine-wide truth (full rationale in `src/state.ts`). The pre-0.5.0\n * Host file + `/catppuccin/state` route are gone — the Host migrates the\n * old file into the store once.\n * At boot the plugin fast-applies localStorage, then hydrates from the scope\n * snapshot once it resolves and mirrors it back into localStorage; if the\n * document holds nothing while this browser session already chose something,\n * that choice is pushed to the document. Every user change is written to\n * localStorage immediately and pushed to the scope (debounced) so it\n * survives the next Desktop restart. Without a usable scope (memory mode /\n * absent transport) everything degrades to localStorage alone. The debounced\n * write is read-side guarded (item C/X): a flush whose base revision the\n * document has moved past abandons the stale write, re-adopts the remote\n * state, and tells the update row \"另一窗口已更新,本地改动未保存\".\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ThemeRuntime, ThemeTokens } from '@deepseek-ai/dsh-client-ui-theme/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the renderer's Context merge (ctx.slots) — since DSH\n// 0.1.2 the slots registry lives in dsh-client-ui-renderer (the old\n// dsh-client-runtime package is gone).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\n// Type-only: pulls the settings-surface SlotMap merge (settings.general.item)\n// and, on 0.1.7+, the configForms Context merge the durable scope binds.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { CatppuccinRow, type CatppuccinRowInjected } from './CatppuccinRow.tsx'\nimport { CatppuccinDetailCard, type CatppuccinDetailCardInjected } from './detail-card.tsx'\nimport { de, en, es, fr, ja, ko, zh, type CatppuccinKey } from './locales.ts'\nimport { LinksRow } from './LinksRow.tsx'\nimport { CATPPUCCIN_FLAVORS, type CatppuccinFlavorId, type CatppuccinFlavorInfo } from './palettes.ts'\nimport { SHIKI_TOKENS } from './shiki-tokens.ts'\nimport { GlassLayer } from './glass/glass-layer.ts'\nimport { GlassRow, type GlassRowInjected } from './glass/glass-row.tsx'\nimport { UpdateRow, type UpdateRowInjected } from './UpdateRow.tsx'\nimport type { UpdateCheckPayload } from '../update-check.ts'\nimport { PACKAGE_NAME, UPDATE_CHECK_CLIENT_TIMEOUT_MS, UPDATE_ROUTE_PATH } from '../update-check.ts'\nimport { tolerantRegistration } from '../registration-tolerance.ts'\nimport {\n CATPPUCCIN_ENTRY_ID,\n DEFAULT_AUTO_CHECK,\n DEFAULT_SHIKI_STYLE,\n DEFAULT_UPDATE_CHANNEL,\n hasUnpersistableOverrides,\n isDefaultState,\n sanitizeOverrides,\n settingsSectionFromState,\n settingsSectionsEqual,\n STATE_VERSION,\n type CatppuccinSettingsSection,\n type CatppuccinState,\n type FlavorValue,\n type ShikiStyle,\n type UpdateChannel,\n} from '../state.ts'\nimport {\n createDurableScope,\n cancelDurablePersist,\n createBaseRevisionTracker,\n durableStateFromSnapshot,\n isScopeUsable,\n persistStateToScope,\n scheduleDurablePersist,\n} from './state-sync.ts'\n// The glass stylesheet is intentionally NOT imported here: it ships as the\n// generated `GLASS_CSS_TEXT` string (`glass-css.gen.ts`, built by\n// scripts/gen-glass-css.mjs) and `GlassLayer` mounts/removes the <style>\n// tag on enable/disable — item II (lazy glass CSS).\n\n/** Locale namespace owned by this plugin. */\nexport const NS = 'catppuccin'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The Catppuccin settings row's copy. */\n catppuccin: CatppuccinKey\n }\n}\n\n/** localStorage key carrying the persisted flavour choice. */\nexport const FLAVOR_STORAGE_KEY = 'dsh.catppuccin.flavor'\n\n/** localStorage key recording the last built-in theme preference. */\nexport const RESTORE_STORAGE_KEY = 'dsh.catppuccin.restore'\n\n/** localStorage key carrying the auto-check update preference (item H). */\nexport const AUTO_CHECK_KEY = 'dsh.catppuccin.autoCheck'\n\n/** localStorage key carrying the update channel preference (item I). */\nexport const UPDATE_CHANNEL_KEY = 'dsh.catppuccin.updateChannel'\n\n/** localStorage key carrying the user token overrides JSON (item K). */\nexport const OVERRIDES_KEY = 'dsh.catppuccin.overrides'\n\n/** localStorage key carrying the shiki style preference (item M). */\nexport const SHIKI_STYLE_KEY = 'dsh.catppuccin.shikiStyle'\n\n/** Accepted flavour values — the four registered theme ids plus `off`. These\n * MUST stay in sync with the registered themes (guarded by\n * tests/palettes.spec.ts) because the persisted value is the theme id. */\nexport const CATPPUCCIN_FLAVOR_VALUES = [\n ...CATPPUCCIN_FLAVORS.map((f) => f.themeId),\n 'off',\n] as const\n\n/** `off` means: fall back to the official theme (default). */\nexport type FlavorChoice = (typeof CATPPUCCIN_FLAVOR_VALUES)[number]\n\n/** The flavour whose themeId this is, or `off`. */\nexport function flavorFromThemeId(themeId: string): FlavorChoice {\n return CATPPUCCIN_FLAVORS.some((f) => f.themeId === themeId) ? themeId as FlavorChoice : 'off'\n}\n\n/** The flavour registered for a theme id, or undefined when not a Catppuccin theme. */\nexport function flavorInfo(themeId: string): CatppuccinFlavorInfo | undefined {\n return CATPPUCCIN_FLAVORS.find((f) => f.themeId === themeId)\n}\n\n/** Read the persisted flavour (absent / unknown values mean the default `off`). */\nexport function readFlavor(): FlavorChoice {\n try {\n const raw = localStorage.getItem(FLAVOR_STORAGE_KEY)\n return raw !== null && (CATPPUCCIN_FLAVOR_VALUES as readonly string[]).includes(raw)\n ? raw as FlavorChoice\n : 'off'\n } catch {\n return 'off'\n }\n}\n\n/** Whether localStorage carries an EXPLICIT `off` flavour choice.\n *\n * `readFlavor()` maps both \"no value\" and \"off\" to `off`, and the two are not\n * the same thing: an absent value only means THIS browser/origin never chose\n * (a first visit, cleared site data, or a second Desktop instance that landed\n * on the next free loopback port), while the durable store — which may\n * legitimately hold a flavour picked elsewhere — is machine-wide. Only a\n * literal `off` in storage proves the user (or another window) actually turned\n * the flavour off, which is the case the cross-tab restore must act on\n * (audit F4). */\nexport function readExplicitFlavorOff(): boolean {\n try {\n return localStorage.getItem(FLAVOR_STORAGE_KEY) === 'off'\n } catch {\n return false\n }\n}\n\n/** Persist the flavour choice (storage failures keep the in-memory state). */\nexport function writeFlavor(choice: FlavorChoice): void {\n try {\n localStorage.setItem(FLAVOR_STORAGE_KEY, choice)\n } catch {\n /* in-memory state still applies for this tab */\n }\n}\n\n/** Remember a built-in preference (system/light/dark) whenever the runtime is\n * not on a Catppuccin flavour, so switching the plugin off restores the\n * user's pre-plugin choice instead of dropping them onto 'system'. The boot\n * preference is the settings-document value, so this survives Desktop's\n * per-launch port churn without joining the durable state schema. */\nexport function rememberBuiltinPreference(preference: string): void {\n if ((CATPPUCCIN_FLAVOR_VALUES as readonly string[]).includes(preference)) return\n try {\n localStorage.setItem(RESTORE_STORAGE_KEY, preference)\n } catch {\n /* nothing to restore later — 'off' falls back to 'system' */\n }\n}\n\n/** The preference to restore when turning the flavour off (default: system). */\nexport function readRestoredPreference(): 'system' | 'light' | 'dark' {\n try {\n const raw = localStorage.getItem(RESTORE_STORAGE_KEY)\n return raw === 'light' || raw === 'dark' ? raw : 'system'\n } catch {\n return 'system'\n }\n}\n\n/** Read the persisted auto-check flag (absent means the shipped default: on). */\nexport function readAutoCheck(): boolean {\n try {\n const raw = localStorage.getItem(AUTO_CHECK_KEY)\n return raw === null ? DEFAULT_AUTO_CHECK : raw === 'true'\n } catch {\n return DEFAULT_AUTO_CHECK\n }\n}\n\n/** Persist the auto-check flag. */\nexport function writeAutoCheck(value: boolean): void {\n try {\n localStorage.setItem(AUTO_CHECK_KEY, String(value))\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/** Read the persisted update channel (absent means `latest`). */\nexport function readUpdateChannel(): UpdateChannel {\n try {\n return localStorage.getItem(UPDATE_CHANNEL_KEY) === 'beta' ? 'beta' : DEFAULT_UPDATE_CHANNEL\n } catch {\n return DEFAULT_UPDATE_CHANNEL\n }\n}\n\n/** Persist the update channel. */\nexport function writeUpdateChannel(value: UpdateChannel): void {\n try {\n localStorage.setItem(UPDATE_CHANNEL_KEY, value)\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/** Read the persisted token overrides (unparseable/absent → empty map).\n *\n * Sanitized on read (`sanitizeOverrides`, the same guard the settings document\n * goes through) so localStorage and the durable section always have the SAME\n * shape. Without it a key that is not a `--` token (e.g. `dsw-static-blue-500`\n * typed without the dashes) lives in localStorage only: the hydration compares\n * the two shapes, sees a difference, and \"the document wins\" overwrites the\n * entry — the user's row vanished a debounce-beat after it was typed. */\nexport function readOverrides(): Record<string, string> {\n try {\n const raw = localStorage.getItem(OVERRIDES_KEY)\n if (raw === null) return {}\n return sanitizeOverrides(JSON.parse(raw))\n } catch {\n return {}\n }\n}\n\n/** Persist the token overrides (storage failures keep the in-memory state). */\nexport function writeOverrides(value: Record<string, string>): void {\n try {\n localStorage.setItem(OVERRIDES_KEY, JSON.stringify(value))\n } catch {\n /* in-memory state still applies */\n }\n}\n\nlet overridesSnapshotCache: Record<string, string> | null = null\n\n/** Stable-reference snapshot of the token overrides for `useSyncExternalStore`.\n * `readOverrides()` parses localStorage and returns a NEW object per call —\n * a React store whose getSnapshot returns a fresh reference every time loops\n * forever (\"Maximum update depth exceeded\") and the settings row crashes.\n * This accessor returns the SAME object while the persisted map is unchanged\n * and swaps only when the content actually differs. */\nexport function overridesSnapshot(): Record<string, string> {\n const next = readOverrides()\n const cached = overridesSnapshotCache\n if (cached !== null && JSON.stringify(cached) === JSON.stringify(next)) return cached\n overridesSnapshotCache = next\n return next\n}\n\n/** Read the persisted shiki style (absent means the shipped default). */\nexport function readShikiStyle(): ShikiStyle {\n try {\n return localStorage.getItem(SHIKI_STYLE_KEY) === 'italic-comments' ? 'italic-comments' : DEFAULT_SHIKI_STYLE\n } catch {\n return DEFAULT_SHIKI_STYLE\n }\n}\n\n/** Persist the shiki style. */\nexport function writeShikiStyle(value: ShikiStyle): void {\n try {\n localStorage.setItem(SHIKI_STYLE_KEY, value)\n } catch {\n /* in-memory state still applies */\n }\n}\n\n/**\n * Does this host ship the menu blur that makes a translucent menu surface work?\n *\n * `--dsw-specific-menu` only became translucent together with the blur: upstream\n * 0.1.7-alpha.1 changed it from `var(--dsw-alias-bg-layer-3)` to a literal\n * 58%/50% neutral AND introduced `--dsw-menu-backdrop-filter: blur(40px)\n * saturate(150%)` in the same release (checked against the 0.1.6-alpha.1 tag,\n * which still has the opaque ladder step and no blur token). On an older host —\n * `latest` is still the 0.1.5 line — the same fill would be *plain*\n * transparency: the transcript would show through the menu with nothing to\n * soften it, and the token also paints panels that carry text (queue dock, todo\n * panel, goal bar, job list, stat dialog, …).\n *\n * Read through <body>'s computed style, where ui-theme declares both tokens.\n * `--dsw-mask-blur` is probed first as a sanity check: it exists in every host\n * we support, so an empty read means the theme stylesheet is not in the cascade\n * yet (or the environment exposes no computed styles). Answering \"false\" then\n * is the safe side — the opaque fill is correct for every host that predates\n * the blur.\n */\nexport function hostHasMenuBlur(): boolean {\n if (typeof getComputedStyle !== 'function') return false\n const body = document.body\n if (body === null) return false\n const styles = getComputedStyle(body)\n if (styles.getPropertyValue('--dsw-mask-blur').trim() === '') return false\n return styles.getPropertyValue('--dsw-menu-backdrop-filter').trim() !== ''\n}\n\n/**\n * Token patch for `--dsw-specific-menu`: the flavour's translucent fill stands\n * where the host declares the matching blur (the value lives in palettes.ts),\n * and the opaque pre-0.1.7 ladder step is injected everywhere else. Applied\n * BEFORE the user overrides, so an explicit `--dsw-specific-menu` in the\n * overrides editor still wins.\n */\nexport function menuSurfaceFor(hostHasBlur: boolean): Record<string, string> {\n return hostHasBlur ? {} : { '--dsw-specific-menu': 'var(--dsw-alias-bg-layer-3)' }\n}\n\n/** Built-in preferences the Appearance row can explicitly pick. */\nconst BUILTIN_PREFERENCES = ['light', 'dark', 'system'] as const\ntype BuiltinPreference = (typeof BUILTIN_PREFERENCES)[number]\n\nfunction isBuiltinPreference(value: string): value is BuiltinPreference {\n return (BUILTIN_PREFERENCES as readonly string[]).includes(value)\n}\n\n/** Whether an observed built-in preference wins over the persisted flavour.\n * Only a light/dark value the user explicitly picked in THIS session — the\n * recorded `liveBuiltinPick` from the setTheme wrapper — wins. Values adopted\n * from the settings document at boot/reload (`livePick` null) never win\n * (issue #6: a doc persisted as `ui-theme.preference: light` was mistaken for\n * a user choice and buried the flavour on every refresh/restart), and\n * \"system\" never wins: while a flavour is on, the Catppuccin row is the\n * active controller and the Appearance row must not bury the persisted\n * choice. A user's explicit light/dark pick still wins immediately (matching\n * livePick) and choosing \"off\" in the Catppuccin row restores it. */\nexport function builtinPickWins(\n preference: string,\n livePick: BuiltinPreference | null,\n): boolean {\n if (preference !== 'light' && preference !== 'dark') return false\n return preference === livePick\n}\n\n/** Required services: slots + locale (settings rows) and theme (register +\n * switch). The durable settings transport is NOT a hard dependency: which\n * service provides it depends on the host version (issue #15 — 0.1.7-alpha.1\n * replaced `settingsScope` with `configForms`), so `createDurableScope`\n * binds whichever one appears through its own optional injections. Listing\n * either name here would leave the plugin permanently pending on the other\n * half of the installed base. */\nexport const inject = ['slots', 'locale', 'theme']\n\n/**\n * Register the Catppuccin dictionaries, the flavour themes (lazy — item JJ:\n * only the active flavour is registered, the rest on first selection), and\n * the settings rows.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n // Bilingual balance is enforced by the typed register call (zh + en);\n // ja/ko/es/fr/de ride the untyped language-pack form and are registered\n // as selectable languages (fallback chain → en) so the dictionaries are\n // reachable without an external language pack (item CC).\n //\n // Every call rides `tolerantRegistration` (issue #23): a peer language pack\n // (dsh-locale-pack, …) that already owns a BCP 47 id makes `addLanguage`\n // throw `locale \"ja\" is already registered`, and a raw throw here fails\n // THIS entry → the whole web boot aborts → the desktop's crash rescue\n // disables every third-party plugin. A skipped registration costs nothing:\n // our dictionaries still land (they register into our OWN namespace), and\n // the id collision only means the peer's language entry already stands.\n ctx.effect(() => {\n const disposers = [\n tolerantRegistration(() => ctx.locale.register(NS, { zh, en })),\n tolerantRegistration(() => ctx.locale.register(NS, 'ja', ja)),\n tolerantRegistration(() => ctx.locale.register(NS, 'ko', ko)),\n tolerantRegistration(() => ctx.locale.register(NS, 'es', es)),\n tolerantRegistration(() => ctx.locale.register(NS, 'fr', fr)),\n tolerantRegistration(() => ctx.locale.register(NS, 'de', de)),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'ja', label: '日本語', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'ko', label: '한국어', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'es', label: 'Español', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'fr', label: 'Français', fallback: 'en' })),\n tolerantRegistration(() => ctx.locale.addLanguage({ id: 'de', label: 'Deutsch', fallback: 'en' })),\n ]\n return () => {\n for (const dispose of disposers) dispose()\n }\n }, 'catppuccin: dictionaries')\n\n const theme = ctx.get('theme') as ThemeRuntime\n\n // Lazy theme registration (item JJ): at most the flavour currently in use\n // is registered; selecting a flavour registers it on demand and the fiber\n // disposer releases every registration. Overrides (item K) and the shiki\n // style (item M) are read at registration time, so a preference change\n // re-registers the active flavour with the merged tokens.\n const themeDisposers = new Map<string, () => void>()\n const registerThemeFor = (flavor: CatppuccinFlavorInfo): void => {\n if (themeDisposers.has(flavor.themeId)) return\n // Flavour id for the shiki token lookup: themeId is \"catppuccin-latte\"\n // → key is \"latte\".\n const flavorId = flavor.themeId.replace('catppuccin-', '') as CatppuccinFlavorId\n const shiki = SHIKI_TOKENS[flavorId][readShikiStyle()]\n // Tolerant (issue #23): `theme.register` throws `theme \"…\" is already\n // registered` when another instance of this plugin owns the id (a\n // duplicate install). One reachable path runs it synchronously\n // (applyScopeSnapshot → reapplyThemePrefs, inside the boot effect), so a\n // raw throw could fail the entry; the others (the deferred restore\n // microtask, the storage event) would turn into uncaught errors. A skip\n // is right either way: the theme exists (the peer's copy), `setTheme`\n // below still works, and the no-op disposer memoizes the skip so we do\n // not re-attempt on every override change.\n const disposer = tolerantRegistration(() => theme.register({\n id: flavor.themeId,\n colorScheme: flavor.colorScheme,\n tokens: {\n ...flavor.tokens,\n ...shiki,\n // Host-shape patch (0.1.7 vs the 0.1.5 latest line): keep the menu\n // surface readable on hosts without the menu blur. Below the user\n // overrides on purpose — see menuSurfaceFor().\n ...menuSurfaceFor(hostHasMenuBlur()),\n ...readOverrides(),\n } as ThemeTokens,\n }))\n themeDisposers.set(flavor.themeId, disposer)\n }\n const ensureThemeRegistered = (themeId: string): void => {\n const flavor = flavorInfo(themeId)\n if (flavor !== undefined) registerThemeFor(flavor)\n }\n const disposeThemeRegistrations = (): void => {\n for (const dispose of themeDisposers.values()) dispose()\n themeDisposers.clear()\n }\n ctx.effect(() => disposeThemeRegistrations, 'catppuccin: flavour theme disposers')\n\n // The glass layer: a toggleable glassmorphism skin on top of the Catppuccin\n // themes. It owns its lifecycle (enable flag + knobs persist in\n // localStorage as the in-browser cache; the durable copy is the settings\n // document hydrated/pushed below; every effect is released with this fiber).\n // It is created before the boot-restore effect so hydration can overlay the\n // persisted glass state onto the layer.\n const glass = new GlassLayer(ctx)\n\n // The official settings transport for the Catppuccin durable state. Which\n // seam it is depends on the host version (0.1.7-alpha.1 replaced the\n // `settingsScope` namespace binding with the `configForms` entry form), so\n // the facade picks whichever service the host provides and never blocks\n // this fiber on it. The document is the source of truth; the scope derives\n // from the shared mirror and never blocks on the transport.\n const scope = createDurableScope(ctx)\n\n // The current durable snapshot: flavour from the localStorage cache (the\n // authoritative write target of the settings row) plus the glass layer's\n // remote state and the preference fields. Passed to the debounced scope\n // persist by reference so the flush always captures the freshest values.\n const buildLocalState = (): CatppuccinState => ({\n version: STATE_VERSION,\n // `FlavorChoice` widens to `string` (palettes carry `themeId: string`), but\n // the runtime value is always one of the four theme ids or `off` — the\n // same set as `FlavorValue`, guarded by tests/state.spec.ts.\n flavor: readFlavor() as FlavorValue,\n glass: glass.getRemoteState(),\n autoCheck: readAutoCheck(),\n updateChannel: readUpdateChannel(),\n overrides: readOverrides(),\n shikiStyle: readShikiStyle(),\n })\n\n // Preference pub/sub: the settings rows read/write autoCheck, channel,\n // overrides and shikiStyle through localStorage; any change re-renders the\n // rows (emitPrefs) and the conflict counter feeds the update row's\n // \"另一窗口已更新\" banner (item X).\n const prefsListeners = new Set<() => void>()\n const emitPrefs = (): void => {\n for (const listener of prefsListeners) listener()\n }\n let conflictCount = 0\n const conflictListeners = new Set<() => void>()\n const emitConflict = (): void => {\n conflictCount += 1\n for (const listener of conflictListeners) listener()\n }\n\n // Re-register the active flavour after an override/shiki-style change so\n // the new token mix applies (the disposed registration is replaced by one\n // carrying the merged overrides).\n const reapplyThemePrefs = (): void => {\n const active = theme.getTheme().preference\n const flavor = flavorInfo(active)\n if (flavor === undefined || !themeDisposers.has(flavor.themeId)) return\n disposeThemeRegistrations()\n registerThemeFor(flavor)\n }\n\n // Debounced push of the current local state into the settings document.\n // When the scope is not usable (memory mode / absent transport) the write\n // is skipped entirely — localStorage stays the only store, exactly the\n // pre-0.5.0 route-missing fallback. The write is read-side guarded (item\n // C/X): a flush whose base revision the document moved past returns\n // `stale`, the local change is abandoned, and the remote state is\n // re-adopted + surfaced in the update row.\n let lastWrittenSection: CatppuccinSettingsSection | undefined\n let handleStaleConflict: (() => void) | undefined\n // R2 (2026-10-10 review): whether a local change was made while the durable\n // scope was NOT yet usable — the boot window, when the settings service\n // lands late or its first snapshot is still in flight. Such a change has no\n // channel to be pushed through yet, and the FIRST snapshot the scope later\n // resolves may describe an OLDER document — without this flag the hydration\n // below would \"adopt the document\" and silently roll the change back. The\n // flag makes the first usable snapshot push the local state instead; a\n // section that already equals the local state makes the queued write a\n // noop, so the ordinary boot path pays nothing.\n let pendingLocalPush = false\n // The revision the pending write is based on, captured when the change is\n // SCHEDULED (audit F2): reading it at flush time made the read-side staleness\n // guard compare a revision with itself — both reads sit in one synchronous\n // block — so `'stale'` was unreachable and an external edit inside the\n // debounce window was silently overwritten. One capture per burst.\n const baseRevisionTracker = createBaseRevisionTracker()\n const queuePersist = (): void => {\n // Marked at SCHEDULE time, not at flush time: the dangerous window is\n // \"change happened before the scope first became usable\", which includes\n // the debounce beat BEFORE the flush runs (a scope that turns ready\n // inside that beat would hydrate and roll the change back before the\n // flush ever sees it).\n if (!isScopeUsable(scope.getSnapshot())) pendingLocalPush = true\n baseRevisionTracker.capture(() => scope.getSnapshot().revision)\n scheduleDurablePersist(persistLocal)\n }\n const persistLocal = (): void => {\n // Consume the base first: a bail-out (unusable scope) must not leave it\n // behind for the next burst.\n const baseRevision = baseRevisionTracker.take()\n const snapshot = scope.getSnapshot()\n if (!isScopeUsable(snapshot)) return\n const state = buildLocalState()\n void persistStateToScope(scope, state, { baseRevision, lastWrittenSection }).then((outcome) => {\n if (outcome === 'written') {\n lastWrittenSection = settingsSectionFromState(state)\n } else if (outcome === 'stale') {\n emitConflict()\n handleStaleConflict?.()\n }\n })\n }\n\n // Auto-check (item H): the last verdict the periodic checker stored (the\n // update row surfaces it on mount) plus the arm hook the preference\n // setter re-invokes on toggle (the timers themselves live in the restore\n // effect below, so they die with the fiber).\n const AUTO_CHECK_BOOT_DELAY_MS = 3000\n const AUTO_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000\n let lastAutoResult: UpdateCheckPayload | null = null\n let armAutoCheck: (() => void) | undefined\n\n // Restore the persisted choice and defend it against the built-in\n // Appearance scope's `adopt()`. Two stores feed the desired flavour:\n // localStorage (the in-browser cache — instant at boot and the cross-tab\n // `storage` bus) and the durable store (the source of truth — required\n // because localStorage is per-browser and per-origin while the DSH home is\n // machine-wide; see `src/state.ts`).\n //\n // The re-assert is not a fixed boot window. The built-in ThemeRuntime's\n // `adopt()` re-applies the settings-document preference on every settings\n // reload — and switching the model always reloads the settings document —\n // writing \"system\" when `ui-theme.preference` was never written, or the\n // persisted light/dark when the document holds one. adopt() writes the\n // runtime preference directly and bypasses setTheme, so the setTheme wrapper\n // below is the one seam that tells explicit picks apart: we restore our\n // flavour whenever the runtime preference is NOT a built-in value the user\n // clicked in the Appearance row THIS session, and choosing \"off\" in the\n // Catppuccin row clears the persisted flavour before the switch so this\n // guard does not fight it.\n ctx.effect(() => {\n // Session-live record of the user's last EXPLICIT built-in pick, kept by\n // the setTheme wrapper below. The wrapper is the only seam that\n // distinguishes \"the user clicked light/dark/system in the Appearance\n // row\" from \"ThemeRuntime.adopt() copied the settings document's value\n // at boot/reload\" — adopt() writes the preference directly and never goes\n // through setTheme, so a doc-adopted light/dark leaves this null and the\n // guard below cannot mistake it for a user choice. Picking a Catppuccin\n // flavour (or the wrapper's own flavour restore) clears the record.\n let liveBuiltinPick: BuiltinPreference | null = null\n const originalSetTheme = theme.setTheme\n // Named on purpose (R1, 2026-10-10 review): the cleanup below may only\n // restore the original while the method is still OUR wrapper. Another\n // extension replacing it afterwards owns the slot by then, and an\n // unconditional write-back of the original would silently unhook it.\n const restoreGuardSetTheme = (id: string): void => {\n liveBuiltinPick = isBuiltinPreference(id) ? id : null\n originalSetTheme.call(theme, id)\n }\n theme.setTheme = restoreGuardSetTheme\n\n // Issue #10: a synchronous setTheme inside a theme/change dispatch\n // re-enters publish() — the ThemePresenter (registered after us) then\n // applies the STALE snapshot carried by the OUTER dispatch last, so the\n // DOM ends up dark/system while the runtime preference is the flavour.\n // Defer the restore out of the current dispatch (microtask) and re-check\n // at run time, so the flavour's setTheme is always the LAST event the\n // presenter sees. A single in-flight restore coalesces repeated\n // observations (boot, adopt() reloads, storage echoes).\n let restorePending = false\n // `desired` is widened to string on purpose: the SAME deferred path also\n // carries the built-in restore (audit F4) — when the persisted choice went\n // 'off' somewhere else, the theme to apply is a built-in preference\n // (`system`/`light`/`dark`), not a flavour id.\n const scheduleRestore = (desired: string): void => {\n if (restorePending) return\n restorePending = true\n queueMicrotask(() => {\n restorePending = false\n const preference = theme.getTheme().preference\n if (preference === desired) return\n // Re-check the guard at run time: a newer explicit built-in pick\n // (or a newer event) still wins over the persisted flavour.\n if (builtinPickWins(preference, liveBuiltinPick)) return\n // Lazy registration (item JJ): the theme must exist before setTheme.\n ensureThemeRegistered(desired)\n try {\n theme.setTheme(desired)\n } catch {\n // Theme not registered yet — a later theme/change re-runs applyDesired.\n }\n })\n }\n\n const applyDesired = (): void => {\n // Record the built-in preference on every non-flavour observation (boot,\n // adopt() reloads, explicit Appearance changes) BEFORE any re-assert, so\n // 'off' below can hand the user back exactly what they had.\n rememberBuiltinPreference(theme.getTheme().preference)\n const desired = readFlavor()\n if (desired === 'off') {\n // The persisted choice is off — but this session may still be rendering\n // a Catppuccin flavour (another window or the settings document turned\n // it off). Hand the user back their built-in preference, exactly like\n // the row's own `select('off')` path. Gated on an EXPLICIT 'off' in\n // localStorage (audit F4): an empty storage may just mean this\n // browser/origin never chose, so the absence of a value is NOT a choice\n // and the durable store — which may legitimately restore a flavour — is\n // authoritative. Without that gate we would fight the document on every\n // boot of a fresh origin.\n const preference = theme.getTheme().preference\n if (readExplicitFlavorOff() && flavorFromThemeId(preference) !== 'off') {\n scheduleRestore(readRestoredPreference())\n }\n return\n }\n const preference = theme.getTheme().preference\n if (preference === desired) return\n // A built-in preference only wins if the user explicitly picked it in\n // THIS session (matching liveBuiltinPick). \"system\" and boot/adopt()\n // values adopted from the settings document (liveBuiltinPick null) are\n // stale for the plugin — the Catppuccin row choice is newer than the\n // document's light/dark, so restore the flavour then.\n if (builtinPickWins(preference, liveBuiltinPick)) return\n scheduleRestore(desired)\n }\n applyDesired()\n const disposer = ctx.on('theme/change', applyDesired)\n const onStorage = (event: StorageEvent): void => {\n if (event.key !== FLAVOR_STORAGE_KEY) return\n const next = readFlavor()\n if (next !== 'off') {\n ensureThemeRegistered(next)\n try {\n theme.setTheme(next)\n } catch {\n /* unknown persisted value — keep the current theme */\n }\n return\n }\n // Another window turned the flavour off (audit F4): this tab must land on\n // the built-in preference too, or it keeps rendering Catppuccin while the\n // persisted choice — and the settings row of the other window — say off.\n if (flavorFromThemeId(theme.getTheme().preference) === 'off') return\n try {\n theme.setTheme(readRestoredPreference())\n } catch {\n /* keep the current theme rather than dropping the user into nothing */\n }\n }\n window.addEventListener('storage', onStorage)\n\n // Any glass change (enable flag or knob) coalesces into one durable write.\n const offGlass = glass.subscribe(() => {\n queuePersist()\n })\n\n // Hydrate the durable source of truth without blocking paint. The scope\n // derives from the shared settings mirror (no wire read of its own), so\n // this is sync once the mirror has resolved; if it arrives later, the\n // subscription below catches it — the localStorage fast path keeps\n // working in the meantime.\n //\n // The hydration is echo-safe: the Host folds our own committed writes\n // back into the mirror, and when the echoed section equals the local\n // state (the normal case after a change we just persisted) we skip the\n // write-back. A section that differs is an external edit (another\n // surface, a hand-edited document, a reload) — the document wins.\n const applyScopeSnapshot = (): void => {\n const snapshot = scope.getSnapshot()\n const state = durableStateFromSnapshot(snapshot)\n if (state === null) return // loading / memory / absent — localStorage-only\n const local = buildLocalState()\n // R2: a change made before the scope first became usable wins over the\n // first usable snapshot (see `pendingLocalPush`). Re-queue it and skip\n // this adoption pass entirely — the queued write is a noop when the\n // section already equals the local state.\n if (pendingLocalPush) {\n pendingLocalPush = false\n queuePersist()\n return\n }\n // The channel owns the \"does the document hold a user layer yet?\" test:\n // the new form's `user` is an empty object until someone writes, while\n // the legacy document omits it entirely.\n if (!scope.hasUserLayer(snapshot)) {\n // No user layer in the document yet: this session's localStorage\n // choice is newer than the shipped defaults the document resolves\n // to, so push it into the document (the upgrade path for a\n // localStorage-only session predating the settings migration).\n if (!isDefaultState(local)) queuePersist()\n return\n }\n // A document holding unpersistable override entries (a hand-edited key\n // that is not a `--` token) can never compare equal to the sanitized\n // local shape, so every publish would re-run this adoption forever.\n // Adopt, then push the cleaned map back once so the document converges\n // (audit F7).\n if (hasUnpersistableOverrides((snapshot.value as { overrides?: unknown } | undefined)?.overrides)) {\n queuePersist()\n }\n // A document the user wrote wins over the local cache, but echoes of\n // our own committed writes are skipped (they equal the local state).\n if (settingsSectionsEqual(\n settingsSectionFromState(local),\n settingsSectionFromState(state),\n )) return // our own echo — nothing to adopt\n writeFlavor(state.flavor)\n glass.applyRemote(state.glass)\n writeAutoCheck(state.autoCheck)\n writeUpdateChannel(state.updateChannel)\n writeOverrides(state.overrides)\n writeShikiStyle(state.shikiStyle)\n emitPrefs()\n reapplyThemePrefs()\n applyDesired()\n }\n applyScopeSnapshot()\n const offScope = scope.subscribe(applyScopeSnapshot)\n\n // Auto-check (item H): warm the Host's verdict cache at boot and every\n // 6 hours while the preference is on. The row surfaces the last result\n // and the Host cache keeps re-opens instant; failures stay uncached so\n // the next cycle retries for real.\n const runAutoCheck = async (): Promise<void> => {\n try {\n const response = await fetch(`${UPDATE_ROUTE_PATH}?channel=${readUpdateChannel()}`, {\n headers: { accept: 'application/json' },\n // R3: same client-side cap as the manual check — a periodic probe\n // must never pile up behind a wedged host.\n signal: AbortSignal.timeout(UPDATE_CHECK_CLIENT_TIMEOUT_MS),\n })\n if (response.ok) lastAutoResult = await response.json() as UpdateCheckPayload\n } catch {\n /* best-effort; the row's retry discipline covers the user-visible UX */\n }\n }\n let bootTimer: number | undefined\n let intervalTimer: number | undefined\n const armAutoCheckImpl = (): void => {\n window.clearTimeout(bootTimer)\n window.clearInterval(intervalTimer)\n if (!readAutoCheck()) return\n bootTimer = window.setTimeout(() => { void runAutoCheck() }, AUTO_CHECK_BOOT_DELAY_MS)\n intervalTimer = window.setInterval(() => { void runAutoCheck() }, AUTO_CHECK_INTERVAL_MS)\n }\n armAutoCheck = armAutoCheckImpl\n armAutoCheckImpl()\n\n handleStaleConflict = () => applyScopeSnapshot()\n\n return () => {\n offScope()\n offGlass()\n disposer()\n window.removeEventListener('storage', onStorage)\n window.clearTimeout(bootTimer)\n window.clearInterval(intervalTimer)\n cancelDurablePersist()\n handleStaleConflict = undefined\n armAutoCheck = undefined\n // Undo the setTheme wrapper so a stopped plugin leaves the runtime as\n // it found it — but only while the wrapper is still ours (R1): if\n // another extension replaced it after us, that replacement is the\n // current owner and force-writing the original back would unhook it\n // without a trace.\n if (theme.setTheme === restoreGuardSetTheme) {\n theme.setTheme = originalSetTheme\n } else {\n console.warn('[dsh-catppuccin] theme.setTheme was replaced by another extension; leaving it in place')\n }\n }\n }, 'catppuccin: theme restore')\n\n const injected = (): CatppuccinRowInjected => ({\n themes: CATPPUCCIN_FLAVORS.map((flavor) => ({\n id: flavor.themeId,\n label: flavor.label,\n accent: flavor.accent,\n })),\n current: () => {\n const pref = theme.getTheme().preference\n return flavorFromThemeId(pref)\n },\n subscribe: (listener) => ctx.on('theme/change', listener),\n select: (choice: FlavorChoice) => {\n if (choice === 'off') {\n // Restore the built-in preference the user had before the flavour\n // ('system' when nothing was recorded). Persist the abandoned choice\n // BEFORE setTheme: setTheme emits theme/change synchronously, so the\n // restore guard must already read `off` here and not re-assert the\n // previous flavour.\n writeFlavor('off')\n // Wrapped like every other setTheme call (issue #23 audit): a throw\n // here used to escape into the row's click handler; keep the current\n // theme instead of dropping the user into nothing.\n try {\n theme.setTheme(readRestoredPreference())\n } catch {\n /* keep the current theme rather than dropping the user into nothing */\n }\n queuePersist()\n return\n }\n const flavor = flavorInfo(choice)\n if (!flavor) return\n // Persist first so the restore guard (a theme/change listener) sees the\n // new flavour when setTheme below emits synchronously. Lazy\n // registration: the theme must exist before setTheme (item JJ).\n writeFlavor(flavor.themeId)\n ensureThemeRegistered(flavor.themeId)\n try {\n theme.setTheme(flavor.themeId)\n } catch {\n /* theme unavailable — keep the current one; a later theme/change retries */\n }\n queuePersist()\n },\n overrides: overridesSnapshot,\n setOverrides: (overrides: Record<string, string>) => {\n writeOverrides(overrides)\n emitPrefs()\n reapplyThemePrefs()\n queuePersist()\n },\n shikiStyle: () => readShikiStyle(),\n setShikiStyle: (style: ShikiStyle) => {\n writeShikiStyle(style)\n emitPrefs()\n reapplyThemePrefs()\n queuePersist()\n },\n subscribePrefs: (listener: () => void) => {\n prefsListeners.add(listener)\n return () => { prefsListeners.delete(listener) }\n },\n })\n\n // Every row registration rides `tolerantRegistration` (issue #23): the\n // callback runs SYNCHRONOUSLY when the slot is already declared (the\n // renderer's documented contract), so a duplicate id at the same priority\n // (`list slot \"…\" already has an entry with id \"…\"`, e.g. a duplicate\n // install) would otherwise throw straight through apply() and fail the\n // boot. A skipped row costs nothing: the occupant is the same row.\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin',\n order: 20,\n locale: NS,\n inject: injected,\n }, CatppuccinRow)))\n\n const glassInjected = (): GlassRowInjected => ({\n getState: () => glass.getSnapshot(),\n subscribe: (listener) => glass.subscribe(listener),\n setEnabled: (enabled) => { glass.setEnabled(enabled) },\n setMode: (mode) => { glass.setMode(mode) },\n setBlur: (blur) => { glass.setBlur(blur) },\n setFrost: (frost) => { glass.setFrost(frost) },\n setBrightness: (brightness) => { glass.setBrightness(brightness) },\n resetDefaults: () => { glass.resetDefaults() },\n })\n\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin-glass',\n order: 21,\n locale: NS,\n inject: glassInjected,\n }, GlassRow)))\n\n // Update check: the Host owns the npm lookup (Node fetch, no CORS); the row\n // only fetches the same-origin route and renders the verdict. Upgrade stays\n // a terminal action — the row just surfaces the CLI command.\n const updateInjected = (): UpdateRowInjected => ({\n check: async (channel: UpdateChannel) => {\n try {\n const response = await fetch(`${UPDATE_ROUTE_PATH}?channel=${channel}`, {\n headers: { accept: 'application/json' },\n // R3 (2026-10-10 review): cap the host hop. The route's own registry\n // lookup is capped at 8s (UPDATE_FETCH_TIMEOUT_MS), so this budget\n // only bites when the host process itself stopped answering —\n // without it the row's `checking` phase (and its disabled button)\n // could stay pinned forever. The abort lands in the catch below as\n // the same `network.local` as any other failed hop.\n signal: AbortSignal.timeout(UPDATE_CHECK_CLIENT_TIMEOUT_MS),\n })\n return await response.json() as UpdateCheckPayload\n } catch {\n return { ok: false, code: 'network.local', error: 'network.local' }\n }\n },\n autoCheck: () => readAutoCheck(),\n setAutoCheck: (value: boolean) => {\n writeAutoCheck(value)\n emitPrefs()\n queuePersist()\n armAutoCheck?.() // re-arm the boot/periodic timers on toggle\n },\n channel: () => readUpdateChannel(),\n setChannel: (channel: UpdateChannel) => {\n writeUpdateChannel(channel)\n emitPrefs()\n queuePersist()\n },\n subscribePrefs: (listener: () => void) => {\n prefsListeners.add(listener)\n return () => { prefsListeners.delete(listener) }\n },\n lastAutoResult: () => lastAutoResult,\n subscribeConflict: (listener: () => void) => {\n conflictListeners.add(listener)\n return () => { conflictListeners.delete(listener) }\n },\n conflictCount: () => conflictCount,\n // Timestamps must follow the interface language, not the browser locale\n // (`toLocaleString()` with no argument silently uses the latter).\n activeLocale: () => ctx.locale.getLocale().active,\n subscribeLocale: (listener: () => void) => ctx.locale.subscribe(listener),\n })\n\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin-update',\n order: 22,\n locale: NS,\n inject: updateInjected,\n }, UpdateRow)))\n\n // Feedback & support row (2026-10-11): closes the section with two static\n // GitHub links — the issue tracker and the repo (the star ask). Pure copy,\n // so it registers WITHOUT an inject factory (only the locale seat); live\n // edits to the URLs belong in LinksRow.tsx. Rendered in both homes: the\n // General section here and the plugin detail card below.\n ctx.slots.inject('settings.general.item', () => tolerantRegistration(() => ctx.slots.register({\n name: 'settings.general.item',\n id: 'catppuccin-links',\n order: 23,\n locale: NS,\n }, LinksRow)))\n\n // Plugins-page card: the settings section on this plugin's OWN detail page in\n // the Plugin manager (DSH >= 0.2.0-rc.2). Three things about this\n // registration are contracts, not style (see `src/client/detail-card.tsx`):\n // - `key` is the BUNDLE PACKAGE NAME, because the page dispatches with\n // `{ entryKey: pkg.name }` — NOT `CATPPUCCIN_ENTRY_ID`, which keys the\n // settings namespace;\n // - the section exists only while this registration does, so `whileServed`\n // withdraws it with the namespace instead of leaving an empty block;\n // - the face is the SAME three factories the General rows use, so the second\n // home shares the durable section rather than a copy of it.\n // `whileServed` is guarded because not every host past 0.1.7 serves it, and\n // `slots.inject` waits for the slot's DECLARATION — a host without the Plugin\n // manager never fires it (no throw, no pending state).\n const detailInjected = (): CatppuccinDetailCardInjected => ({\n flavor: injected(),\n glass: glassInjected(),\n update: updateInjected(),\n })\n\n ctx.inject(['configForms'], (formsCtx) => {\n const forms = formsCtx.configForms\n if (typeof forms.whileServed !== 'function') return\n return forms.whileServed([CATPPUCCIN_ENTRY_ID], () => ctx.slots.inject(\n 'plugins.bundle.config',\n () => tolerantRegistration(() => ctx.slots.register({\n name: 'plugins.bundle.config',\n key: PACKAGE_NAME,\n locale: NS,\n inject: detailInjected,\n }, CatppuccinDetailCard)),\n ))\n })\n}"],"mappings":"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"}