
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-qq-skin
Advanced tools
QQ 风格皮肤插件 for DeepSeek Harness: overlays a Tencent QQ messenger look on the Web client through the official theme token layer (ctx.theme.overrideTokens).
A QQ NT messenger skin for DeepSeek Harness (dsh). Light and dark share one QQ NT language — light mode is clean and restrained (near-white surfaces, neutral borders/hover, brand blue #12B7F5 and light-blue bubbles #A8E3FF as recognition accents), dark mode is a calm blue-gray (base #101822, desaturated, blue reserved for accents), instantly recognizable. Ships with five palette variants (Classic Blue / Vivid Purple / Clean White / Green Bubble / Deep Black), configurable toggles and sizing, plus a settings-panel visual switcher with hot reload.
How it works. The skin is two reversible layers; it never registers a new theme id and never touches the user's Light/Dark/System preference.
- Token layer — stacks one
--dsw-*semantic-token override viactx.theme.overrideTokens('dsh-qq-skin', ...). Every token carries a{ light, dark }pair, so the skin follows the active base palette instead of fighting it. Light mode runs blue through surfaces, borders, interactions, and scrollbars; the dark palette is a#101822-based calm blue-gray scale where blue only accents (brand, bubbles, primary buttons). The set is generated per palette (buildTokenOverrides(palette)): the five palettes share the neutral blue-gray skeleton and differ only in the personality tokens.- Layout layer — injects one global
<style>tag (qq-layout.ts) for geometry and structure: the chat flow is centered and narrowed, user bubbles are light blue with a "tail", assistant rows get an avatar disc + white card (matched viadata-chat-flow-kind='assistant-step'), the input area becomes a capsule, plus a slim conversation-header divider, QQ-styled timestamps and scrollbar, and sidebar session-row hover/selected states. The brand area stays product-native — the QQ feel comes entirely from the blue token layer. Colors always come from--dsw-*tokens, and dark variants are gated bybody[data-ds-dark-theme]. The CSS is generated from the config (buildQQLayoutCss).On unload both layers are fully removed through effect cleanup and the product look returns. Settings and config changes hot-reapply both layers via
QQSkinRuntime.updatewithout restarting the plugin.
The chat view in the Classic Blue palette: centered, narrowed chat flow, light-blue user bubbles with a "tail", and the penguin avatar disc on assistant rows:

The QQ Skin settings row in the App settings General section, with the palette / bubble tail / assistant avatar / chat width toggles:

The skin registers a QQ Skin settings row in the App settings General section, with visual toggles for palette / bubble tail / assistant avatar / chat width. Changes apply immediately (hot reload remounts both layers) and are persisted to the user-settings document. The settings panel overrides the static config below.
The plugin receives config the cordis function-plugin way (apply(ctx, config)); unset fields fall back to defaults:
| Option | Default | Meaning |
|---|---|---|
palette | 'classic' | Palette variant: classic Classic Blue / vivid Vivid Purple / clean Clean White / green Green Bubble / black Deep Black |
bubbleTail | true | Small triangular "tail" on the right of user bubbles |
assistantAvatar | true | Official QQ-penguin avatar disc left of assistant messages |
chatMaxWidth | 880 | Max width of the chat flow (px) |
Example (set in the profile's plugin config):
{ "palette": "vivid", "bubbleTail": false, "chatMaxWidth": 720 }
| Area | Mechanism |
|---|---|
| Brand & primary actions (QQ blue) | --dsw-alias-brand-primary, --dsw-alias-button-primary-*, --dsw-alias-state-business-* |
| Canvas & surfaces (clean light) | --dsw-alias-bg-base (#F7F9FB), --dsw-alias-bg-layer-1..3, --dsw-alias-bg-overlay |
Conversation bubbles (light blue #A8E3FF) | --dsw-specific-bubble, --dsw-specific-bubble-highlight + layout-layer radius/shadow |
| Assistant messages | layout-layer avatar disc (token colors) + white card with border (--dsw-alias-bg-layer-1 + border-l1) |
| Chat flow | layout-layer centering (via data-chat-flow, width configurable) |
| Input bar | layout-layer capsule (data-composer-card) + toolbar button radius + --dsw-specific-input-major |
| Conversation header | layout-layer slim divider (header[class$='_header'], never hits side panels) |
| Message timestamps | layout-layer QQ-style chips (data-time-hover-root + _timeStart/_timeEnd) |
| Sidebar session rows | layout-layer hover/selected fill + status-dot radius (_sessionRow/_projectRow/_dot) |
| Scrollbar | layout-layer widening + radius (data-conversation-scroll) + --dsw-alias-scrollbar-* |
| Sidebar (clean light / blue-gray dark) | --dsw-specific-sidebar-fill (#F2F5F8), --dsw-specific-sidebar-nav-item-* + layout-layer divider |
| Text & borders | --dsw-alias-label-*, --dsw-alias-border-l1..l4 (blue-tinted strokes) |
| Status colors (QQ green/red/amber) | --dsw-alias-state-success/error/warn-* |
| Static palette (component-direct, unified sky blue) | --dsw-static-deepseek-*, --dsw-static-blue-* (remapped to the #12B7F5 sky-blue scale) |
| Markdown, scrollbar (QQ blue), menus, tooltips | --dsw-alias-markdown-*, --dsw-alias-scrollbar-*, --dsw-specific-menu, --dsw-alias-tooltip-bg |
Tokens that are not overridden keep the product default, so a QQ-skin run stays readable and consistent everywhere else.
Built and run against deepseek-harness (dsh) 0.2.0 or later. dsh 0.2 changed two settings-system contracts (2026-10):
ctx.settings.register(ns, schema) is gone: the plugin's settings schema is now the Config export of its host entry, and every field must be .volatile() — the settings panel projects volatile fields only, so a non-volatile field appears in no descriptor and accepts no write. The namespace comes from the id of the entry in cordis.patch.yml (qq-skin), not from a string the plugin picks.ctx.configForms. The ctx.settingsScope service is gone: the client uses ctx.configForms.get('qq-skin'), whose snapshot value is the fully resolved host config (schema defaults → profile config → user edits) and whose set(field, value) persists an edit. A 0.2 client entry no longer receives a config argument at all, so the built-in defaults only cover the first frame.settings.configure({ auto: false }) to suppress the auto-generated page.Earlier dsh versions (0.1.x) are not compatible: they have no settings.configure, no ctx.configForms, and no volatile config projection.
One command installs the plugin into the web profile:
dsh plugin --profile web add dsh-qq-skin
That is the whole flow: dsh plugin initializes the profile on first use,
runs pnpm add dsh-qq-skin inside the profile directory, then reconciles the
profile's bundle layer against the installed state — because dsh-qq-skin
declares dsh.bundle.patch (→ cordis.patch.yml), it joins the bundle stack
automatically. The next dsh web boot composes it, the client bundle loads,
and the skin stacks as soon as ui-theme is active.
Installing from a local checkout (path specs are anchored to your invoking
directory; link: keeps the live checkout linked):
dsh plugin --profile web add ../dsh-qq-skin
dsh plugin --profile web add link:../dsh-qq-skin
Removing is equally one command:
dsh plugin --profile web remove dsh-qq-skin
The plugin declares dsh.client with platform: web and injects the theme,
slots, locale, remote, and configForms services, so the Web boot loads
its client bundle and applies the layer as soon as ui-theme is active.
pnpm install
pnpm run typecheck # tsc --noEmit
pnpm test # vitest (token shape + layout injection + runtime hot reload + settings wiring)
pnpm run build # tsc + tsdown → lib/index.js (host) + lib/client.js (browser closure-factory)
The client bundle is produced by the same two-face layout as the harness
clientBundle preset: lib/index.js is the plain ESM host row, lib/client.js
is the window.__ModuleLoader__ closure-factory the Web boot consumes. No
build-time CSS pipeline is needed: the layout styles ship as an inline string
inside the client bundle (QQ_LAYOUT_CSS in qq-layout.ts) and are injected at
runtime via document.createElement('style') — the same shape as ui-theme's
installThemeStyles — then removed on effect dispose. Layout selectors rely on
the client CSS Modules [hash]_[local] naming ([class$="_localName"]
suffix matches) and the components' own data-* hooks, never on build-time
hash values.
The settings row (settings-row.tsx) uses inline token styles reading --dsw-*
directly, so it adds no CSS Modules pipeline; react and the collaboration
services stay external to the client bundle and resolve through the platform
module table.
MIT
FAQs
QQ 风格皮肤插件 for DeepSeek Harness: overlays a Tencent QQ messenger look on the Web client through the official theme token layer (ctx.theme.overrideTokens).
We found that dsh-qq-skin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.