DSH Chat Image Lightbox

August 30, 2026 · View on GitHub

English | 中文


English

A DeepSeek Harness plugin that displays images inline in the chat with a lightbox overlay — zoom, download (save-as dialog), and prev/next navigation.

Features

  • Inline display: Images in AI responses render directly in the chat (via markdown ![alt](url))
  • Click to zoom: Click any image to open a full-screen lightbox; click again to zoom back out
  • Scroll to zoom & pan: When zoomed in, use the mouse wheel to zoom further and drag to pan around the image
  • Download: Click the download button ⬇ to save the image (triggers browser save-as dialog for same-origin images; filename is sanitized and the extension is derived from the image type)
  • Navigation: Left/right arrow buttons, keyboard arrows, or swipe left/right on touch devices to switch between multiple images
  • Caption: The viewer shows the current image's filename/caption
  • Accessible: The lightbox is a proper role="dialog" with aria-modal, button aria-labels, and focus management (focus returns to the trigger on close)
  • Smooth: Adjacent images are prefetched so navigation feels instant
  • Close: Click backdrop, press Escape, or click ✕ to close
  • Thumbnail grid: When one AI message contains multiple images, they automatically collapse into a tidy fixed 3-column grid (9 images = 3×3, 6 = 3×2, even rows); the grid shows light, fast thumbnails (auto ?w= resized, so large originals are not downloaded into small tiles)
  • HD original on open: Clicking any thumbnail opens the lightbox with the full-resolution original image (the ?w= thumbnail param is stripped) — zooming in shows the real high-resolution file
  • Clean UI: The lightbox toolbar (download / close), prev/next arrows, counter and caption are hidden whenever the lightbox is closed — they only appear while you are actually viewing an image, so they never clutter the chat layout
  • Auto-enhance: MutationObserver automatically enhances new images added to the chat

Installation

dsh plugin --profile desktop add @loyalchiiina/dsh-chat-image-lightbox

Method 2: Manual

  1. Copy the lib/ folder and cordis.patch.yml to your DSH profile's node_modules/@loyalchiiina/dsh-chat-image-lightbox/
  2. Add @loyalchiiina/dsh-chat-image-lightbox to your profile's package.jsondsh.profile.bundles array
  3. Restart DSH Desktop

Usage

  1. Place images in ~/.dsh/uploads/ (or any directory served by your DSH instance)
  2. In your AI response, use markdown image syntax:
    ![Description](http://127.0.0.1:<port>/images/your-image.jpg)
    
  3. The image will display inline with lightbox enhancement

Note: For the download button to trigger a save-as dialog, the image must be served from the same origin as your DSH instance (e.g., via the /images/ route). Cross-origin images will open in a new tab instead.

Troubleshooting image display (important)

When an image shows as blank, a blob of text, or the lightbox opens empty, check in this order:

① Images must use an http(s) URL — base64/data-URI and attachments are NOT rendered

DSH renders images into <img> only from http(s) URLs. It does not render data:image/png;base64,... inline, nor "file-delivery/attachment" messages (those appear as tool-call text, not an image).

  • ✅ Correct — markdown + http URL:
    ![Description](http://127.0.0.1:<port>/images/your-image.jpg)
    
  • ✅ Correct — any non-hotlink-protected external image:
    ![Description](https://some-cdn.com/image.jpg)
    
  • ❌ Will NOT render — base64 inline:
    ![Description](data:image/png;base64,....)
    

Some hosts (e.g. Sina Weibo sinaimg, some CDNs) enforce Referer-checking: a request without the expected Referer returns 403, so the image frame renders but no pixels load (clicking still opens the lightbox, but there is no image).

  • No normal webpage can hotlink these directly (including all sites except Weibo) — this is not something any plugin can fix.
  • Workaround: download the image to ~/.dsh/uploads/ (fetch with a proper Referer, or just save it from the browser), then serve it via /images/.

Example — fetching a hotlink-protected image (Windows):

curl -e "https://weibo.com" -o image.jpg "https://wx1.sinaimg.cn/.../xxx.jpg"

③ Supported image formats

FormatRendered by browserNotes
jpg / jpeg / png / gif / webp / bmp / svg / ico✅ YesMainstream formats — display + lightbox work
tiff❌ NoBrowsers cannot render tiff in <img>; no plugin can show it directly — convert to png/jpg first
heic❌ NoApple iPhone format — convert first

Converting tiff / heic (needs Python + Pillow):

python -c "from PIL import Image; Image.open('image.tif').convert('RGB').save('image.png')"
# Downscale huge files first: Image.open('image.tif').convert('RGB').thumbnail((2000,2000)) then save

Put the resulting png in ~/.dsh/uploads/ and display via /images/.

④ Plugin not working after changes — restart fully

After installing or editing plugin files, fully quit all DSH Desktop processes (Task Manager → end every DSH Desktop.exe) and reopen. Closing just the window does not quit (background processes stay). Old/unloaded code keeps the plugin inactive otherwise.

⑤ Is it actually the plugin? Quick checklist

  • Test with a /images/-served upload — if it displays and lightboxes, the plugin is fine.
  • Test with a non-hotlink-host image (e.g. https://picsum.photos/800/600) — if that works, the plugin is generic.
  • If neither uploads nor external images lightbox → the plugin client didn't load, usually because DSH wasn't fully restarted or the install is incomplete.

Keyboard & Mouse

ActionInput
Open lightboxClick an image
Zoom in / outClick image, or mouse wheel when zoomed
PanDrag the image while zoomed
Prev / next / keys, on-screen arrows, or swipe
CloseEsc, click backdrop, or ✕

HTTP API

EndpointMethodDescription
/images/<path>GETServe an uploaded image (loopback-only, with extension/security guards)
/api/image-gallery/listGETList images under the gallery root; supports ?limit=N
/api/image-gallery/rootGETReturn the configured gallery root path

How It Works

ComponentDescription
Host (lib/index.js)Registers /images/ file-serving route and /api/image-gallery/list + /api/image-gallery/root APIs on ctx.webServer
Client (lib/client.js)Uses MutationObserver to watch for <img> elements in the chat, adds click handlers that open a lightbox overlay

Requirements

  • DeepSeek Harness ≥ 2.0 (with webServer service)
  • Node.js ≥ 22

License

MIT


中文

DeepSeek Harness 插件:在对话框中直接显示图片,支持放大、下载(弹出另存为)、左右切换。

功能

  • 内联显示:AI 回复中的图片直接在对话框渲染(通过 markdown ![描述](url)
  • 点击放大:点击任意图片打开全屏 lightbox,再点一次缩回
  • 滚轮缩放 + 拖拽平移:放大后可用鼠标滚轮继续缩放,按住拖拽平移查看细节
  • 下载:点击下载按钮 ⬇ 保存图片(同源图片弹出"另存为"对话框;文件名会清洗,扩展名按图片类型自动补全)
  • 切换:左右箭头按钮、键盘方向键,或在触屏上左右滑动切换多张图片
  • 文件名:查看器底部显示当前图片的文件名/标题
  • 无障碍:lightbox 是标准的 role="dialog"(含 aria-modal、按钮 `aria-label$ 与焦点管理,关闭后焦点回到触发元素)
  • 预取:自动预取相邻图片,切换更顺滑
  • 关闭:点击遮罩层、按 \text{Esc} 或点 ✕ 关闭
  • 缩略图网格:当一条 \text{AI} 消息里包含多张图片时,自动折叠成整齐的固定 3 列网格(9 张=3 \times 3、6 张=3 \times 2,行数整齐);网格显示轻量快速缩略图(自动 $?w=` 缩放,不会把大原图下载进小格子)
  • 点开即高清原图:点击任意缩略图打开 lightbox 时,直接加载全分辨率原图(去掉 ?w= 缩略参数),放大看到的是真正的原图清晰度
  • 界面干净:lightbox 的工具按钮(下载/关闭)、左右切换箭头、计数、标题在 lightbox 关闭时全部隐藏,仅在实际看图时才显示,不会在对话界面留下按钮干扰布局
  • 自动增强:MutationObserver 自动增强新加入对话的图片

安装

方式一:npm(推荐)

dsh plugin --profile desktop add @loyalchiiina/dsh-chat-image-lightbox

方式二:手动安装

  1. lib/ 文件夹和 cordis.patch.yml 复制到 DSH profile 的 node_modules/@loyalchiiina/dsh-chat-image-lightbox/
  2. 在 profile 的 package.jsondsh.profile.bundles 数组中添加 @loyalchiiina/dsh-chat-image-lightbox
  3. 重启 DSH Desktop

使用方法

  1. 把图片放到 ~/.dsh/uploads/ 目录(或 DSH 实例提供的任意目录)
  2. AI 回复中使用 markdown 图片语法:
    ![描述](http://127.0.0.1:<端口>/images/你的图片.jpg)
    
  3. 图片会内联显示并自动带 lightbox 增强

注意:下载按钮要弹出"另存为"对话框,图片必须从 DSH 同源路由提供(如 /images/ 路由)。跨域图片会在新标签页打开。

图片显示常见问题排查(重要)

遇到"图片显示不出来 / 点开是空白 / 只看到一串文字"时,按以下顺序排查:

① 图片必须用 DSH 能识别的 URL 显示,不能依赖 base64 或附件

DSH 对话只对http(s) 图片 URL渲染成 <img>不支持 data:image/png;base64,... 内嵌,也不支持以"附件/文件交付"方式直接显示(那只会显示成工具调用文字)。

  • ✅ 正确:markdown 图片语法 + http URL
    ![描述](http://127.0.0.1:<端口>/images/你的图片.jpg)
    
  • ✅ 正确:任意无防盗链的外链图片
    ![描述](https://某个图床.com/图片.jpg)
    
  • ❌ 错误:base64 内嵌(DSH 渲染不出,只看到一串 iVBORw0...
    ![描述](data:image/png;base64,....)   ← 不会显示
    

② 图片空白 / 点开灯箱没图案 = 图源防盗链(图床限制,非插件问题)

部分图床(如新浪微博 sinaimg、部分 CDN)强制 Referer 校验:请求不带特定 Referer 就返回 403,导致图片加载不出(有 <img> 框但内容空白,点击能弹灯箱但没图)。

  • 这类图任何普通网页都无法直接外链显示(包括微博自己以外的所有站点),不是本插件能解决的。
  • 解决办法:把图下载到本地 ~/.dsh/uploads/(可用带 Referer 的脚本抓取,或直接用浏览器保存),再通过 /images/ 路由显示。

示例:抓取带防盗链的图(Windows 下用带 Referer 的 curl 或脚本下载后放入 uploads):

curl -e "https://weibo.com" -o 图.jpg "https://wx1.sinaimg.cn/.../xxx.jpg"

③ 支持哪些图片格式

格式浏览器直接显示说明
jpg / jpeg / png / gif / webp / bmp / svg / ico✅ 支持主流格式,直接显示 + 灯箱
tiff❌ 不支持Web 浏览器 <img> 不原生渲染 tiff,任何网页/插件都无法直接显示;需转成 png/jpg
heic❌ 不支持同上,苹果手机图片格式,需转码

tiff / heic 转码方法(安装 Python + Pillow):

python -c "from PIL import Image; Image.open('图.tif').convert('RGB').save('图.png')"
# 超大图建议先缩小:Image.open('图.tif').convert('RGB').thumbnail((2000,2000)) 再 save

转出的 png 放到 ~/.dsh/uploads/,用 /images/ 显示。

④ 彻底重启后插件不生效

改过插件文件或刚安装后,必须彻底退出 DSH 进程再重开(任务管理器结束所有 DSH Desktop.exe 进程),否则旧代码/未加载状态不生效。仅"关闭窗口"不算退出(后台进程残留)。

⑤ 判断是不是插件问题的清单

  • /images/ 上传图测:如果上传图正常显示 + 灯箱,说明插件正常
  • 换无防盗链图床(如 picsum.photos)的图测:正常则插件通用
  • 若上传图、外链图都不亮灯箱 → 插件 client 未加载,多半是没彻底重启或没装正确

键盘与鼠标

操作输入
打开 lightbox点击图片
放大 / 缩小点击图片,或放大后滚动滚轮
平移放大后按住拖拽
上一张 / 下一张 / 方向键、屏幕箭头、或滑动
关闭Esc、点击遮罩层、或 ✕

HTTP 接口

接口方法说明
/images/<path>GET提供上传图片(仅本机回环,带扩展名/安全校验)
/api/image-gallery/listGET列出图库根目录下图片,支持 ?limit=N
/api/image-gallery/rootGET返回配置的图库根目录路径

工作原理

组件说明
Host (lib/index.js)ctx.webServer 上注册 /images/ 文件服务路由和 /api/image-gallery/list + /api/image-gallery/root 接口
Client (lib/client.js)MutationObserver 监听对话中的 <img> 元素,添加点击处理器打开 lightbox

环境要求

  • DeepSeek Harness ≥ 2.0(需要 webServer 服务)
  • Node.js ≥ 22

许可证

MIT