npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@loyalchiiina/dsh-chat-image-lightbox

v1.7.1

Published

对话里的图值得被认真看:点一下全屏灯箱(缩放/拖拽平移/下载另存/左右翻页),会话内一键把图收成可调列数的缩略图网格或整块隐藏,还能跳到下一张/上一张图片位置;本地图支持 TIFF/HEIC 自动转码。| Chat images get a proper look: full-screen lightbox (zoom / drag pan / download / prev-next), plus one-click conversation-wide thumbnail grid (configura

Readme

DSH Chat Image Lightbox 🖼

对话里的图,值得被认真看。

Images in chat deserve a proper look.

English | 中文

📦 npm 包名 / npm package name:@loyalchiiina/dsh-chat-image-lightbox GitHub 仓库名是 dsh-chat-image-lightbox,但 npm 上带 scope 前缀,安装时请用完整名。 The GitHub repo is dsh-chat-image-lightbox; the npm package is scoped — use the full name when installing.

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

图片灯箱全屏查看

灯箱全屏态:原图完整显示(自动适配屏幕高度),右上角是「⬇ 下载」与「✕ 关闭」按钮;同一条消息里的其他图片可用方向键连续浏览。 Full-screen lightbox: the image auto-fits the viewport, with ⬇ download and ✕ close in the top-right; arrow keys page through the other images in the same message.


功能总览 · At a glance(中英对照 / Bilingual)

灯箱查看 · Lightbox viewer

| 中文 | English | |---|---| | 点击任意对话图片进入全屏灯箱 | Click any chat image for a full-screen lightbox | | 滚轮缩放、拖拽平移 | Wheel zoom, drag to pan | | 工具栏缩放按钮 ⊕ ⊖ 与 1× 复位 | Toolbar ⊕ / ⊖ zoom buttons with 1× reset | | 方向键平移视角(按住连续移动) | D-pad moves the view (press-and-hold repeats) | | 左右翻页:按钮 / 键盘 / 触屏滑动 | Prev/next via toolbar, keyboard or swipe | | 下载原图(自动识别扩展名) | Download original (extension auto-detected) | | 复制图片文件绝对路径 | Copy the image's absolute local path | | 在文件夹中显示(资源管理器定位) | Reveal in folder (file manager locates the file) |

会话级图片控制 · Conversation-wide controls

| 中文 | English | |---|---| | 一键把整个会话图片收成缩略图网格 | Collapse every image in the conversation into a thumbnail grid | | 网格列数可调(1–12,设置被记住) | Configurable columns per row (1–12, remembered) | | 一键隐藏 / 展开所有图片 | Hide / restore all images at once | | 跳图定位:左键上一张、右键下一张、三连最远/最近 | Jump: left = prev, right = next, triple = farthest / nearest | | 落点闪一下高亮 | Landing block flashes briefly |

格式与清晰度 · Formats & fidelity

| 中文 | English | |---|---| | TIFF/TIF、HEIC 自动转换显示 | TIFF/TIF, HEIC auto-transcode for display | | TIFF/PNG/BMP 无损原像素(逐像素零误差) | TIFF/PNG/BMP lossless, native pixels (bit-exact) | | 2 亿像素大图流畅显示 | 200-megapixel images display smoothly | | 11 种格式实测支持(JPG/PNG/WebP/GIF/AVIF/SVG/BMP…) | 11 formats verified (JPG/PNG/WebP/GIF/AVIF/SVG/BMP…) |

宿主侧工具 · Host-side tool (display_image)

| 中文 | English | |---|---| | 关键词搜网图(花瓣/Bing/搜狗 3 源回退) | Keyword image search (Huaban / Bing / Sogou fallback) | | 搜图自动过滤广告与他人面孔 | Auto-filters adverts & other celebrities | | 本地文件/目录直读(TIFF/HEIC 转码) | Read local files/dirs (TIFF/HEIC transcoded) | | 网图落地保存到本地目录 | Save remote images to a local folder | | 代理自动探活(无需手配) | Auto proxy discovery (TCP probe) |

隐私与安全 · Privacy & safety

| 中文 | English | |---|---| | 一切本地服务仅回环(loopback-only) | All local services are loopback-only | | 打开文件夹用参数化调用,绝不拼接 shell 命令 | "Show in folder" spawns argv, never a shell string | | 保存说明不回显本机路径 | No local paths echoed in confirmations |


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.

Pictures from your agent sit tiny inside a bubble — to see detail you have to save them and open elsewhere. With this plugin, one click opens any chat image full-screen: zoom, drag-pan, download, and flip through the others in the same message.

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
  • ZCode-style rendering: chat images are styled in place — never moved, resized or reparented — so DSH's React virtual list is never fought with (no more vanished/duplicated images or console removeChild errors)
  • Capped, not cropped: every chat image renders with its aspect ratio preserved, capped at min(460px, 64vh) height (the ZCode look); charts and diagrams stay fully readable
  • Responsive image row: when one message contains multiple images in one container, they lay out as a responsive CSS-grid row — via a class on the container only, without moving any nodes
  • HD original on open: clicking any image opens the lightbox with the full-resolution original image — 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
  • Zoom / pan pad: the lightbox also has explicit controls for what the gestures do — ⊖ ⊕ 1× for zoom with a live percentage readout, and a d-pad for moving the view (press and hold to keep moving). Wheel, drag and +/-/Shift+arrow all still work
  • Conversation-wide image controls in one popover: a single compact 「🖼 图片」 trigger sits next to the access-mode control and slides out a panel holding all four actions — no row of buttons cluttering the composer
  • Thumbnail grid with configurable columns: one click collapses every image block in the conversation into a CSS grid of small tiles (captions span the full row). A number field sets the columns per row (1–12), remembered across reloads
  • Hide / show whole blocks: one click hides every image (each block collapses to a slim strip), another click brings them back intact
  • Jump to image: one button for locating images — left click steps to the previous image, right click to the next; left triple-click jumps to the farthest image from the viewport centre, right triple-click to the nearest. The landing block flashes. Stepping is relative to the last landed block and stops at the ends
  • Auto-enhance: MutationObserver automatically enhances new images added to the chat, and re-adopts images whose class a React re-render overwrote
  • Bring images into the chat (display_image tool, host side): one tool takes a local path (file or directory — TIFF/HEIC transcoded, optional downscale), a remote url, or a query (keyword image search: Huaban first, Bing as fallback) and returns ready-to-paste Markdown. Any file on this machine can be served in place via /images/?abs=<path> (loopback-only), no copying into the gallery root required

Installation

Method 1: npm (recommended)

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.json → dsh.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,....)

② Blank image / empty lightbox = hotlink protection on the image host (source limit, not this plugin)

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

| Format | Displayed | Notes | |--------|-----------|-------| | jpg / jpeg / png / gif / webp / bmp / svg / ico / avif | ✅ Directly | Mainstream formats — display + lightbox work, bytes untouched | | tiff / tif | ✅ Via server conversion | Browsers can't render TIFF; the plugin server converts it to WebP at full original resolution (bundled sharp) — HD display, and download keeps the original .tif | | heic | ✅ Via server conversion | Same as TIFF — displayed as WebP, downloaded as the original .heic |

Files go in ~/.dsh/uploads/ and display via /images/ — no manual conversion needed.

④ 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

| Action | Input | |--------|-------| | Open lightbox | Click an image | | Zoom in / out | Click image, or mouse wheel when zoomed | | Pan | Drag the image while zoomed | | Prev / next | ← / → keys, on-screen arrows, or swipe | | Close | Esc, click backdrop, or ✕ |

HTTP API

| Endpoint | Method | Description | |----------|--------|-------------| | /images/<path> | GET | Serve an uploaded image (loopback-only, with extension/security guards) | | /api/image-gallery/list | GET | List images under the gallery root; supports ?limit=N | | /api/image-gallery/root | GET | Return the configured gallery root path |

How It Works

| Component | Description | |-----------|-------------| | 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 a display class + click handlers that open a lightbox overlay (class-only enhancement, no DOM restructuring) |

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 与焦点管理,关闭后焦点回到触发元素)
  • 预取:自动预取相邻图片,切换更顺滑
  • 关闭:点击遮罩层、按 Esc 或点 ✕ 关闭
  • ZCode 式渲染:聊天图片原地加样式——绝不搬移、改父级或重排 DOM 节点,不与 DSH 的 React 虚拟列表打架(不再出现图片消失/重复、控制台 removeChild 报错)
  • 限高不裁剪:每张聊天图保持原始纵横比,高度封顶 min(460px, 64vh)(ZCode 的观感);图表、流程图不再被裁得没法看
  • TIFF/HEIC 直显:浏览器原生不渲染 TIFF——插件服务端用内置 sharp 将 TIFF/HEIC 按原始分辨率即时转 WebP 显示(本地图表导出照样高清直显),下载按钮保存的仍是原始 .tif/.heic 文件
  • 多图九宫格:一条消息里有多张图时自动排成整齐网格(约 3 列),文字段落横跨整行排在网格上方——纯 CSS(display:contents),不搬任何节点
  • 点开即高清:点击任意图片打开 lightbox 看全分辨率大图,放大看到每个像素;下载永远保存原始文件
  • 界面干净:lightbox 的工具按钮(下载/关闭)、左右切换箭头、计数、标题在 lightbox 关闭时全部隐藏,仅在实际看图时才显示,不会在对话界面留下按钮干扰布局
  • 灯箱缩放/平移面板:手势能做的都给了一组显式按钮——⊖ ⊕ 1× 缩放(带实时百分比),加一组方向键移动视角(按住可连续移动);滚轮、拖拽、+/-/Shift+方向键 全部保留
  • 会话内图片控制收进一个弹出面板:输入框旁的「完全权限」右侧只留一个紧凑的 「🖼 图片」 触发器,点它滑出面板,四个操作都在里面——不再让一排按钮占着输入区
  • 可调列数的缩略图网格:一键把整个会话的图片收成小图网格(标题横跨整行);面板里有「列」输入框可设每行几张(1–12),设置会被记住(刷新/重启后仍生效)
  • 整块隐藏 / 展开:一键隐藏所有图片(每个图片块收成一条窄边),再点一下原样恢复——所有内联样式按块追踪并清理,图片不会丢
  • 跳图定位:一个按钮定位图片——左键跳到上一张、右键跳到下一张;左键三连跳到离屏幕中心最远的一张、右键三连跳到最近的一张;落点会闪一下。步进是相对「上次落点」的,并且到头即止不回绕(回绕会让人以为方向反了)
  • 自动增强:MutationObserver 自动增强新加入对话的图片;React 重渲染覆盖 class 后也会自动重新接管
  • 把图带进对话(宿主侧 display_image 工具):一个工具吃三种输入——本地 path(文件或目录,TIFF/HEIC 自动转码、可缩放)、网络 url 直链、query 关键词搜图(花瓣优先,Bing 回退),返回可直接粘贴的 Markdown。本机任意文件可通过 /images/?abs=<路径> 原地直读(仅限本机回环),无需先复制进图库目录

安装

方式一: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.json → dsh.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 / avif | ✅ 直接显示 | 主流格式,直接显示 + 灯箱,字节原样不动 | | tiff / tif | ✅ 服务端转码显示 | 浏览器不能渲染 TIFF,插件服务端用内置 sharp 按原始分辨率转 WebP 显示——高清直显,下载仍是原始 .tif 文件 | | heic | ✅ 服务端转码显示 | 同 TIFF——显示为 WebP,下载保存原始 .heic |

图片放到 ~/.dsh/uploads/,用 /images/ 显示——无需手工转码。

④ 彻底重启后插件不生效

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

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

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

键盘与鼠标

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

HTTP 接口

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

工作原理

| 组件 | 说明 | |------|------| | Host (lib/index.js) | 在 ctx.webServer 上注册 /images/ 文件服务路由和 /api/image-gallery/list + /api/image-gallery/root 接口 | | Client (lib/client.js) | 用 MutationObserver 监听对话中的 <img> 元素,添加展示样式与点击处理器打开 lightbox(只加 class,不改 DOM 结构) |

环境要求

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

许可证

MIT