vecnode/vn-code--packages-dsh-themes ↗★ 9
dsh-themes
Themes and header dress: the conversation header's own controls (page zoom, Screenshot, Themes, session-log download), the Nord/Monokai/Hacker/Cyber palettes, and the pack's appearance overrides - Markdown paper, the branding band, the account menu's Feedback row removed, and the right bar's resize seam. 适合需要个性化界面配色(如暗黑模式)以及常用辅助控制功能的用户。
Other repositories with this package name
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:vecnode/vn-code#066e7396f8c7d4abd3132329f32c1b7c9ad8c1fa&path:packages/dsh-themesREADME
Read the full README ↗dsh-themes (alpha.27)
The vncode Web GUI's conversation-header package: four controls on that header, plus the pack's appearance overrides.
All four are occupants of the Session header's conversation.session.header.utilities list, which renders in ascending order — lower is
further left. The package is control and dress only: it forks nothing and disables no core row.
| Occupant | Order | Position |
|---|---|---|
| Page zoom | -40 | leftmost |
| Screenshot | -30 | left of Themes |
| Themes | -20 | left of Open In… |
| Session-log download | 0 | the shipped session-log-download seat |
Open In… (dsh-open-in-app) is -10 and dsh-cmdbar's button 30; no shipped order is changed.
What it adds
- Themes (
-20) — a menu of Light / Dark / System plus every theme in the shipped registry. The package registers Nord, Monokai, Hacker and Cyber throughctx.theme.register, as alias-token overrides on the dark base. Hacker is the phosphor CRT (green-cast black, green text, amber and cyan accents); Cyber is the second high-contrast programmer palette and deliberately not its twin (blue-cast black, near-white body, magenta brand, cyan link).THEME_EXTENSIONSorder is menu order: Light, Dark, Nord, Monokai, Hacker, Cyber, System. The preference and its persistence stay ui-theme's: this control reads the published snapshot and callssetTheme(id); an extension id, which the durable schema cannot hold, lives inui-state's volatile config and is cleared by a built-in pick. - The Session-log download seat (
0) — the shipped three-dot More actions menu replaced by one download button, by the registry's own shadowing rule: the same occupantid(session-log-download) atpriority: -10, so the shipped registration stays mounted (it owns the export) and stops rendering. The control resolvessessionLogDownloadlazily, draws the same preparing / success / error dialog, and is disabled when that row is absent. - Screenshot (
-30) —getDisplayMediaon the current tab, one frame into a canvas, POSTed to this package's host route. The open tooltip bubble is kept out of the frame byhtml[data-dsh-screenshot] [role=tooltip]. - Page zoom (
-40) — Chrome's own ladder, cut at both ends:50, 67, 75, 80, 90, 100, 110, 125, 150, 175, 200. It writes one inlinezoomon the document element and removes it at 100%. It exists because the native windowscripts\run-desktop.batopens has no Ctrl+ / Ctrl- gesture; the button sits inside the page it zooms, hence the 200% top rung. The level is kept inui-state's volatilepageZoom, with alocalStoragecopy underdsh-themes.page-zoom. - Appearance overrides, plain CSS: the Markdown paper (ui-theme's own light declarations re-read at
boot and re-declared on
body [data-document-markdown], plus white — all-or-nothing, re-installed ontheme/change); the Markdown chrome (the viewer menu hidden on the shipped Markdown renderer alone); the left column's top bar, whose branding band takes the other columns' hairline at y=76, with the VN branding (assets/vncode.svginlined as a data URI, a 24px mark, the namevncode) centred on the band's own top row; the header ring on[data-conversation-header-corner] button; the account menu's Feedback row, hidden on the paper-planepathartwork; the right bar's resize seam, placed from a CSS anchor underhtml[data-dsh-page-zoomed]; the left column's panel order (regionArea1,panelList2,footArea3); the band lines — the same.5pxhairline the band already ends in, drawn a second time on the frame's y=40 in ALL THREE columns: between the middle column's button row and its session tabs, under the left column's branding row, and in the right bar 2px into the row below its 38px tab strip (that band's own rows divide at 38, not 40, so the line cannot hang on the strip's edge if all three are to start at the same height) — and, with it, the top row's centre: that line splits every band into a 40px top row and a 36px one below, so all three columns' top-row furniture (the branding row's mark, name and collapse toggle, the conversation title and its 28px controls, the dock strip's 28px tab chips) is centred on the frame's y=20, 6px clear of the rule, rather than resting on it — plus the 38px bar the right bar's Start tab was missing, so every tab's hairline lands at y=76 like the Files, History, editor, Diagrams, PDF, image, video and audio tabs' own tool bars already do, and the surface for that row, because the right bar is an overlay: the tab body's own box is painted with the bar's own--dsw-alias-bg-baseand the Start tab's bar wears it as its border colour, so the row under the line is the bar rather than a window onto the conversation behind it; and the fullscreen right panel'swidth:100%while a zoom is in force. Hooks are stable app markers (data-conversation-header-corner,data-rightbar-col,data-dockkit-strip,role="menuitem") or hashed class names.
How it plugs in
cordis.patch.ymlinserts thethemesrow and patches nothing else.lib/index.jsregisters one authenticated route,POST /api/dsh-themes/screenshot, whose body is the PNG.lib/client.jsdraws the four header occupants, the theme entries and the stylesheets. It injectsslotsplus@deepseek-ai/dsh-client-ui-themeand@deepseek-ai/dsh-client-ui-conversation;theme,uiStateandsessionLogDownloadusectx.get, neverinject, so a profile without them still gets a header.
Limits
- The screenshot route accepts
image/pngonly, requires the real PNG signature and a body under 64 MiB, and writes create-exclusively asvncode-.pngto the Desktop resolved per request — Windows or OneDrive-redirected,XDG_DESKTOP_DIR, home folder last. Failures are typed (415/400/413/500), the client never names a path, and without the host row the browser download is the fallback. - A hashed-class pin stops matching after a harness rename: a no-op, not a broken layout, and the Feedback row would simply return.
- The mid-band line is drawn in the wide left column only. Collapsed, the shell draws one 36px square where the wide row draws a mark, a name and a 28px button, and that square fills its whole 36px strip (y=2..38), so a line at y=40 would run through it.
- The right bar's row surface is painted by this package because the bar is an overlay on the frame: the tab
body's own box takes
--dsw-alias-bg-base, the token the forked bar's own stylesheet paints the dock with. A tab that wants a different surface paints it on top, as every tab body already does. - Under a page zoom,
vhand pointer coordinates stay unscaled whilegetBoundingClientRect()does not, so a drag that compares pointer deltas against a rect moves by the zoom factor.
Verify
node scripts/checks/check-client-bundles.mjs # seats, orders, the ladder, the paper, the seam, the band lines, the top row's centre
node scripts/checks/check-node-routes.mjs # the screenshot route: type, signature, cap, Desktop write
Install
scripts\setup\install.bat on Windows, ./scripts/setup/install.sh on macOS/Linux: the launcher auto-discovers this package as a standard dsh.bundle,
and a bundle the profile does not list yet is added by one plain run. The web profile live-links it from this repo, so a code edit needs a
restart of npx @deepseek-ai/dsh web plus a hard refresh; scripts\run-web.bat / ./scripts/run-web.sh starts it and opens the printed URL.