EIGHTfs / dsh-image-preview

Listed

DSH 会话内图片预览插件:静态图片服务 + 文本渲染(双字体防乱码) + SVG转PNG,让 AI 在会话里直接发图片

mainOther View source

Installation

npx -y @deepseek-ai/dsh plugin --profile web add github:EIGHTfs/dsh-image-preview

This installation command is an unverified starting point generated from the GitHub repository address.

README

Maintainer-authored documentation snapshot.

View on GitHub ↗
Commit 618826cSynced Aug 18, 2026

🖼️ dsh-image-preview

让 AI 在 DSH 会话里直接给你发图片 —— 静态图片服务 + 文本渲染 + SVG 转换,一条 API 全搞定

功能示意

✨ 为什么需要它?

DSH 的 AI 会话回复是纯文本的,想让用户直接看到一张图片(截图、二维码、配图)时:

  • ❌ 让用户去翻文件目录 —— 麻烦
  • ❌ 手动起 python3 -m http.server —— 每次都要开服务、记端口
  • ❌ 直接在 markdown 里写本地路径 —— GUI 渲染不了

dsh-image-preview 把这一切变成插件内置能力:AI 在回复里贴一个 markdown 图片 URL,用户直接在对话中看到图,无需任何手动操作

📦 核心能力

接口方法说明
/api/image-preview/file?path=xxxGET静态图片服务:暴露工作区文件,AI 回复里贴 URL 即可渲染
/api/image-preview/renderPOST文本 → PNG:AI 把要展示的内容发给接口,生成图片
/api/image-preview/svg2pngPOSTSVG → PNG:GitHub 架构图等 SVG 转成可预览的 PNG
/api/image-preview/statusGET插件状态:版本 / workspace / Pillow 与字体可用性

用法示例

AI 回复里贴图(最常用):

![架构图](http://<你的主机>:<端口>/api/image-preview/file?path=docs/architecture.png)

渲染一段文字为图片:

curl -X POST http://127.0.0.1:3081/api/image-preview/render \
  -H 'Content-Type: application/json' \
  -d '{"text":"崩溃检测 ×2 全部正确检出","title":"实测记录","outPath":"report.png"}'
# → {"ok":true,"url":"/api/image-preview/file?path=report.png"}

SVG 架构图转 PNG:

curl -X POST http://127.0.0.1:3081/api/image-preview/svg2png \
  -H 'Content-Type: application/json' \
  -d '{"svgPath":"docs/screenshots/architecture.svg","outPath":"architecture.png","outputWidth":960}'

🛡️ 亮点设计

亮点事实
双字体防乱码中文用 Droid/Noto 等 CJK 字体、符号(→·×①等)用 DejaVu,逐字符渲染——不再出现"✅变方块"
emoji 兜底替换✅→✓、🚀→>> 等,任何字体都没有的 emoji 自动转成可渲染文本
路径穿越防护相对路径 normalize 后必须落在 workspace 内,../ 和绝对路径一律拒绝(实测防护通过)
零运行时依赖插件本身是纯 Node.js;渲染走系统 python3 + Pillow(可选),无 npm 依赖
纯服务端apply(ctx) 写法 + webServer 路由,无 client bundle,不碰 UI

📦 安装

方式一:手动安装(三要素)

# 1. 源码放 node_modules_local
mkdir -p ~/.dsh/profiles/web/node_modules_local/dsh-image-preview
cp -r lib package.json cordis.patch.yml ~/.dsh/profiles/web/node_modules_local/dsh-image-preview/

# 2. package.json 加 file: 依赖
node -e "
const fs=require('fs');
const p=JSON.parse(fs.readFileSync('~/.dsh/profiles/web/package.json'));
p.dependencies['dsh-image-preview']='file:./node_modules_local/dsh-image-preview';
fs.writeFileSync('~/.dsh/profiles/web/package.json',JSON.stringify(p,null,2));
"

# 3. cordis.patch.yml 追加
cat >> ~/.dsh/profiles/web/cordis.patch.yml << 'EOF'
- insert:
    - id: dsh-image-preview
      name: dsh-image-preview
EOF

# 重启 DSH 生效

环境要求

  • python3 + Pillow:文本渲染(pip install pillow;本机沙箱只读时用 pip install --break-system-packages --target <dir> + PYTHONPATH
  • python3 + cairosvg:SVG 转换(依赖系统 librsvg)
  • 都没有时插件仍可用:静态图片服务(/file)不依赖它们

🔧 工作原理

AI 会话回复                    DSH 插件                    用户
─────────                     ────────                    ────
回复 markdown ──URL──▶  /api/image-preview/file ──▶   GUI 渲染图片
                              │
回复内容 ──▶ /api/image-preview/render ──生成 PNG──▶   直接看到
                              │
SVG 路径 ──▶ /api/image-preview/svg2png ──转 PNG──▶    直接看到

🧪 测试

测试结果
mock 单元测试(路由注册/路径穿越/渲染核心)✅ 9/9 通过
测试实例真机验证(3083)✅ 插件加载 + status/file/render/svg2png 全接口通过
路径穿越防护../secret 与绝对路径均被拒绝(400)
双字体符号渲染✅ ✅→① 等符号无乱码

运行测试:node test-apply.mjs

📚 设计理念

  1. 给用户的东西必须能打开:地址一律用真实主机 IP(见 host-address-convention),不甩 127.0.0.1
  2. 插件即服务:服务随插件生命周期走,不需要用户手动起/停任何东西
  3. 能力分层降级:核心静态服务零依赖;文本渲染/SVG 转换依赖系统工具,缺失时优雅降级
  4. 安全默认:路径穿越防护 + 只读暴露,绝不给任意文件读取

License

MIT

Project files and signals

Shown items are public repository signals detected in the directory snapshot.

DocumentationDetected

Repository information

Language
JavaScript
License
Not reported
Last updated
Aug 18, 2026, 2:01 PM

Install deliberately

Review source code, permissions, lifecycle hooks, dependencies and network access. Test untrusted plugins in an isolated environment.