Skip to content

Latest commit

 

History

History
101 lines (87 loc) · 8.83 KB

README.md

File metadata and controls

101 lines (87 loc) · 8.83 KB

dsh-themes (alpha.31)

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 through ctx.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_EXTENSIONS order 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 calls setTheme(id); an extension id, which the durable schema cannot hold, lives in ui-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 occupant id (session-log-download) at priority: -10, so the shipped registration stays mounted (it owns the export) and stops rendering. The control resolves sessionLogDownload lazily, draws the same preparing / success / error dialog, and is disabled when that row is absent.
  • Screenshot (-30) — getDisplayMedia on 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 by html[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 inline zoom on the document element and removes it at 100%. It exists because a browser zoom reflows the whole shell while a page zoom does not - the frame keeps its layout, which is what makes it usable on a 1440px screen; the button sits inside the page it zooms, hence the 200% top rung. The level is kept in ui-state's volatile pageZoom, with a localStorage copy under dsh-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 on theme/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.svg inlined as a data URI, a 24px mark, the name vncode) 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-plane path artwork; the right bar's resize seam, placed from the open panel's own left edge as a CSS anchor under html[data-dsh-page-zoomed] (the panel, not the column: at a zoom the solve reads a scaled rect, so at 90% the panel is drawn 616px wide in a 648px track and the column's edge is 32px off the seam); the band's action strip — Settings, Plugins, Media, Skills mounted as four of the app's own 28px .dst-button controls in the 36px row under the vncode band, each naming itself in a tooltip, with the bottom rows they mirror hidden once the strip is there (the one override here that mounts DOM rather than CSS: the sidebar declares no slot for that row, so the theme adds a sibling of the branded identity and drives each destination the way its own row does). Two of the four are deliberate departures from the rows they mirror: Media opens dsh-audio's media dialog (ctx.get('media').open()) instead of selecting the panel behind it, so the conversation stays in the main column; and Skills is the pack's ONE visible entry to that dialog — the header seat dsh-skills still registers is hidden by a :has([data-dsh-themes-band]) rule, because it is what the band's button CLICKS (its click handler carries the session id) and a display:none control still takes a programmatic click. The left column's panel order (regionArea 1, panelList 2, footArea 3); the band lines — the same .5px hairline 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-base and 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's width: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.yml inserts the themes row and patches nothing else.
  • lib/index.js registers one authenticated route, POST /api/dsh-themes/screenshot, whose body is the PNG.
  • lib/client.js draws the four header occupants, the theme entries and the stylesheets. It injects slots plus @deepseek-ai/dsh-client-ui-theme and @deepseek-ai/dsh-client-ui-conversation; theme, uiState and sessionLogDownload use ctx.get, never inject, so a profile without them still gets a header.

Limits

  • The screenshot route accepts image/png only, requires the real PNG signature and a body under 64 MiB, and writes create-exclusively as vncode-<timestamp>.png to 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, vh and pointer coordinates stay unscaled while getBoundingClientRect() 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.