From e8834bd34949bec0fe1bfa15b28bbfd166b95f90 Mon Sep 17 00:00:00 2001 From: Menghuan1918 Date: Thu, 3 Sep 2026 16:47:39 +0800 Subject: [PATCH] feat(theme): drive the last-resort error bar through skin tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The host-anchor fallback diagnostic strip inlined hardcoded colors (#f2a1a1 on #1b1b22). Route them through var() chains like the existing SideChatView.module.css fallback pattern: text/border read --dsw-alias-state-error-primary (the codebase's canonical error color, 23 existing usages) and the background reads --dsw-alias-bg-layer-3,var(--dsw-alias-bg-base,...) (elevated surface, then page base). The old hexes ride as the chain tails, so with no skin tokens on the page the bar renders byte-identical to before, while any --dsw-alias-* skin re-themes it (guide §12: no hardcoded colors). The guide does not cover this strip and tests/theme.spec.ts asserts effectiveTokenValue semantics only, so neither needs a follow-up. --- src/client/index.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/client/index.tsx b/src/client/index.tsx index 2915d42..bf7cc09 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -166,14 +166,21 @@ export function apply(ctx: Context): void { ) // A failure anywhere in the client lifecycle must never take the app down // silently: log with the plugin prefix and pin a visible diagnostic strip - // to the page so a blank panel is never the only symptom. + // to the page so a blank panel is never the only symptom. This strip is + // the last-resort reporter (no CSS module is reachable from here), so its + // colors go through skin token chains with the previous hexes as the + // chain tails — worst case (no skin tokens on the page) it renders + // byte-identical to the old hardcoded bar, and any `--dsw-alias-*` skin + // re-themes it (guide §12: no hardcoded colors). const fail = (phase: string, error: unknown): void => { console.error(`[dsh-better-sidebar] ${phase} error:`, error) try { const bar = document.createElement('div') bar.style.cssText = 'position:fixed;left:8px;bottom:8px;z-index:2147483000;max-width:70vw;padding:8px 12px;' - + 'font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#f2a1a1;background:#1b1b22;' - + 'border:1px solid #f2a1a1;border-radius:8px;white-space:pre-wrap' + + 'font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;' + + 'color:var(--dsw-alias-state-error-primary,#f2a1a1);' + + 'background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-base,#1b1b22));' + + 'border:1px solid var(--dsw-alias-state-error-primary,#f2a1a1);border-radius:8px;white-space:pre-wrap' bar.textContent = `[dsh-better-sidebar] ${phase} error: ${error instanceof Error ? error.message : String(error)}` document.body.appendChild(bar) } catch {