🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

视觉工坊 LR611415/visionforge

DeepSeek Harnessv0.2.1
LR61141525 天前有提交已提供中文文档扫描:含敏感能力

给 DeepSeek Harness 装上「眼睛」和「画笔」:视觉理解 + 图片生成 + 图片编辑,一个插件搞定。

30.8/100
综合分
1
GitHub 星标
465
npm 周下载
—/5
用户评分

数据截至 2026/10/9 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @lr611/visionforge
npm 源 · @lr611/visionforge 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · vision
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 25 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@lr611/visionforge @ 0.2.1
✓Node 引擎要求 >=22.19 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/10 21:28:23

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 165 处,展示前 99 条)
  • 执行外部命令来自配置/变量
    dsh/index.js:86
    const r = spawnSync(probe, [cmd], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] })
  • 读取本地文件
    dsh/index.js:111
    const OUTPUT_SCHEMA = JSON.parse(readFileSync(new URL('./vision-schema.json', import.meta.url), 'utf8'))
  • 读取本地文件
    dsh/index.js:155
    raw = readFileSync(configPath(), 'utf8')
  • 读取本地文件
    dsh/index.js:174
    return existsSync('D:\\') ? 'D:\\VisionForge\\out' : join(homedir(), 'VisionForge', 'out')
  • 读取本地文件
    dsh/index.js:190
    if (!existsSync(file)) return
  • 读取本地文件
    dsh/index.js:195
    if (lstatSync(file).isSymbolicLink()) return
  • 写入本地文件
    dsh/index.js:199
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    dsh/index.js:200
    writeFileSync(file, `${JSON.stringify(cfg, null, 2)}\n`, { mode: 0o600 })
  • 读取本地文件
    dsh/index.js:562
    if (lstatSync(file).isSymbolicLink()) throw new Error(`${file} is a symlink; edit the file it points at instead`)
  • 写入本地文件
    dsh/index.js:566
    mkdirSync(dirname(file), { recursive: true })
  • 写入本地文件
    dsh/index.js:567
    writeFileSync(file, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 })
  • 写入本地文件
    dsh/index.js:569
    chmodSync(file, 0o600)
  • 写入本地文件
    dsh/index.js:578
    mkdirSync(dirname(file), { recursive: true })
  • 执行外部命令固定命令
    dsh/index.js:814
    const child = spawn('cmd.exe', ['/c', 'start', '', file], { detached: true, stdio: 'ignore' })
  • 执行外部命令固定命令
    dsh/index.js:838
    const reveal = spawn('explorer.exe', ['/select,' + dest], { detached: true, stdio: 'ignore' })
  • 执行外部命令固定命令
    dsh/index.js:841
    const fb = spawn('cmd.exe', ['/c', 'start', '', dirname(dest)], { detached: true, stdio: 'ignore' })
  • 执行外部命令固定命令
    dsh/index.js:867
    const reveal = spawn('explorer.exe', ['/select,' + dest], { detached: true, stdio: 'ignore' })
  • 执行外部命令固定命令
    dsh/index.js:870
    const fb = spawn('cmd.exe', ['/c', 'start', '', dirname(dest)], { detached: true, stdio: 'ignore' })
  • 发起网络请求
    dsh/client.js:107
    fetch('/visionforge/paste', {
  • 发起网络请求
    dsh/client.js:195
    return fetch('/visionforge/paste?model=' + encodeURIComponent(label), { method: 'GET' })
  • 发起网络请求
    dsh/client.js:258
    fetch(u.origin + '/visionforge/open?path=' + encodeURIComponent(p), { method: 'GET' }).catch(function () {})
  • 发起网络请求
    dsh/client.js:269
    fetch(u.origin + '/visionforge/download-local?path=' + encodeURIComponent(p), { method: 'GET' })
  • 发起网络请求
    dsh/client.js:433
    fetch(origin + '/visionforge/log?msg=' + encodeURIComponent(msg), { method: 'GET' }).catch(function () {})
  • 发起网络请求
    dsh/client.js:597
    fetch('/visionforge/click-debug?path=' + encodeURIComponent(path), { method: 'GET' }).catch(function () {})
  • 读取本地文件
    src/index.js:107
    (env.HOME && fs.existsSync(path.join(env.HOME, '.dsh'))) ||
  • 读取本地文件
    src/index.js:108
    (env.USERPROFILE && fs.existsSync(path.join(env.USERPROFILE, '.dsh')));
  • 写入本地文件
    src/index.js:163
    fs.mkdirSync(path.dirname(outputPath), { recursive: true });
  • 写入本地文件
    src/index.js:164
    fs.writeFileSync(outputPath, output, 'utf-8');
  • 写入本地文件
    src/index.js:549
    fs.writeFileSync(tempPath, tinyPlaceholderPng());
  • 删除本地文件
    src/index.js:581
    fs.unlinkSync(tempPath);
  • 执行外部命令来自配置/变量
    dsh/spawnHidden.js:19
    return spawn(command, args, { ...options, windowsHide: true })
  • 读取本地文件
    src/analyze.js:52
    if (!fs.existsSync(filePath)) {
  • 读取本地文件
    src/analyze.js:55
    const stat = fs.statSync(filePath);
  • 写入本地文件
    src/analyze.js:76
    fs.copyFileSync(source, imageSource);
  • 写入本地文件
    src/analyze.js:77
    fs.chmodSync(imageSource, 0o600);
  • 读取本地文件
    src/analyze.js:184
    const missingCwd = !fs.existsSync(invocation.cwd);
  • 读取本地文件
    src/cooldown.js:54
    raw = fs.readFileSync(statePath, 'utf-8');
  • 读取本地文件
    src/cooldown.js:91
    if (!fs.existsSync(dir)) {
  • 写入本地文件
    src/cooldown.js:92
    fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
  • 写入本地文件
    src/cooldown.js:94
    fs.chmodSync(dir, 0o700);
  • 写入本地文件
    src/cooldown.js:100
    fs.writeFileSync(tmp, `${JSON.stringify(merged, null, 2)}\n`, { mode: 0o600 });
  • 写入本地文件
    src/cooldown.js:101
    fs.renameSync(tmp, statePath);
  • 写入本地文件
    src/cooldown.js:103
    fs.chmodSync(statePath, 0o600);
  • 删除本地文件
    src/cooldown.js:194
    fs.rmSync(statePath, { force: true });
  • 读取本地文件
    src/doctor.js:68
    text = fs.readFileSync(launcher, 'utf-8');
  • 读取本地文件
    src/doctor.js:207
    const stat = fs.statSync(configPath);
  • 读取本地文件
    src/doctor.js:276
    for (const item of fs.readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    src/doctor.js:283
    size += fs.statSync(full).size;
  • 读取本地文件
    src/doctor.js:328
    for (const profile of fs.readdirSync(profilesDir, { withFileTypes: true })) {
  • 读取本地文件
    src/doctor.js:332
    try { pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); } catch { continue; }
  • 读取本地文件
    src/imagegen.js:59
    return fs.existsSync('D:\\') ? path.resolve('D:\\VisionForge\\out') : path.join(os.homedir(), 'VisionForge', 'out');
  • 读取本地文件
    src/imagegen.js:69
    const entries = fs.readdirSync(dir);
  • 读取本地文件
    src/imagegen.js:77
    const st = fs.statSync(full);
  • 删除本地文件
    src/imagegen.js:79
    fs.unlinkSync(full);
  • 写入本地文件
    src/imagegen.js:356
    fs.mkdirSync(path.dirname(outputPath), { recursive: true });
  • 写入本地文件
    src/imagegen.js:363
    fs.writeFileSync(outputPath, buffer);
  • 写入本地文件
    src/imagegen.js:369
    fs.mkdirSync(path.dirname(outputPath), { recursive: true });
  • 写入本地文件
    src/imagegen.js:379
    fs.writeFileSync(outputPath, buffer);
  • 读取本地文件
    src/providers/index.js:139
    if (fs.statSync(full).isFile()) {
  • 读取本地文件
    src/recover-paste.js:144
    return fs.readFileSync(filePath, 'utf-8').split('\n');
  • 读取本地文件
    src/recover-paste.js:214
    return { file, mtime: fs.statSync(file).mtimeMs };
  • 读取本地文件
    src/recover-paste.js:376
    if (!fs.existsSync(dbPath)) {
  • 读取本地文件
    src/recover-paste.js:398
    if (!fs.existsSync(dbPath)) {
  • 读取本地文件
    src/recover-paste.js:565
    if (fs.existsSync(dir)) {
  • 读取本地文件
    src/recover-paste.js:633
    return { file, mtime: fs.statSync(file).mtimeMs };
  • 写入本地文件
    src/recover-paste.js:737
    fs.mkdirSync(outDir, { recursive: true, mode: 0o700 });
  • 写入本地文件
    src/recover-paste.js:739
    fs.chmodSync(outDir, 0o700);
  • 写入本地文件
    src/recover-paste.js:862
    fs.writeFileSync(filePath, buffer, { mode: 0o600 });
  • 写入本地文件
    src/recover-paste.js:864
    fs.chmodSync(filePath, 0o600);
  • 写入本地文件
    src/config.js:51
    fs.copyFileSync(configPath, backupPath);
  • 读取本地文件
    src/config.js:61
    raw = fs.readFileSync(configPath, 'utf-8');
  • 写入本地文件
    src/config.js:350
    fs.mkdirSync(path.dirname(configPath), { recursive: true });
  • 写入本地文件
    src/config.js:351
    fs.writeFileSync(configPath, `${JSON.stringify(out, null, 2)}\n`, { mode: 0o600 });
  • 写入本地文件
    src/config.js:353
    fs.chmodSync(configPath, 0o600);
  • 读取本地文件
    src/config.js:567
    if (!force && fs.existsSync(configPath)) {
  • 写入本地文件
    src/config.js:570
    fs.mkdirSync(path.dirname(configPath), { recursive: true });
  • 写入本地文件
    src/config.js:571
    fs.writeFileSync(configPath, `${JSON.stringify(CONFIG_TEMPLATE, null, 2)}\n`, { mode: 0o600 });
  • 读取本地文件
    src/reuse.js:99
    return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
  • 读取本地文件
    src/reuse.js:109
    if (fs.statSync(full).isFile()) {
  • 读取本地文件
    src/reuse.js:147
    const loggedIn = fs.existsSync(path.join(codexHome, 'auth.json'));
  • 读取本地文件
    src/reuse.js:148
    if (!fs.existsSync(path.join(codexHome, 'config.toml'))) {
  • 读取本地文件
    src/reuse.js:152
    const toml = fs.readFileSync(path.join(codexHome, 'config.toml'), 'utf-8');
  • 写入本地文件
    src/reuse.js:296
    fs.mkdirSync(path.dirname(cachePath), { recursive: true });
  • 写入本地文件
    src/reuse.js:297
    fs.writeFileSync(cachePath, JSON.stringify({ cachedAt, probes }, null, 2), { mode: 0o600 });
  • 读取本地文件
    src/reuse.js:559
    auth = JSON.parse(fs.readFileSync(path.join(agentDir, 'auth.json'), 'utf-8'));
  • 执行外部命令来自配置/变量
    src/shim.js:17
    return spawn(command, args, { ...options, windowsHide: true });
  • 执行外部命令来自配置/变量
    src/shim.js:21
    return execFileSync(file, args, { ...options, windowsHide: true });
  • 读取本地文件
    src/shim.js:87
    return fs.statSync(target).isDirectory() ? 'directory' : 'present';
  • 读取本地文件
    src/shim.js:102
    if (fs.statSync(full).isFile()) {
  • 读取本地文件
    src/shim.js:138
    readFileSync: (p) => fs.readFileSync(p, 'utf-8'),
  • 读取本地文件
    src/net.js:282
    const size = fs.statSync(filePath).size;
  • 读取本地文件
    src/net.js:286
    const buffer = fs.readFileSync(filePath);
  • 发起网络请求
    src/net.js:319
    const req = mod.request(reqOptions, (res) => resolve(res));
  • 发起网络请求
    src/net.js:553
    const connectReq = http.request({
  • 发起网络请求
    src/net.js:566
    const req = https.request({
  • 发起网络请求
    src/net.js:582
    const req = http.request({
  • 发起网络请求
    src/net.js:594
    const req = mod.request(reqOptions, handleResponse);
  • 读取本地文件
    src/providers/antigravity.js:104
    return { full, mtime: fs.statSync(full).mtimeMs };
  • 删除本地文件
    src/providers/kimi-cli.js:21
    fs.rmdirSync(dir);
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-client-ui-primitives
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 视觉理解
  • 图像生成
  • 图片编辑
v0.2.12026-10-02
· v0.2.1 适配 DSH Desktop v2.0.17 / harness 0.2.0-rc.2(2026-10 实测),并兼容 harness 0.1.7 系列。 · 本版变更 · 适配 harness 0.2.x:peerDependencies 扩展为三段范围(含 0.2.0-rc 系列),插件可在更新后的桌面端正常注册工具与渲染预览 · 提示词质量强化:图生图指令门槛 50 → 100 字,六维检测(主体/动作/场景/光影/构图/画质)词表扩充 · 5-bug 修复: - 多图生成超时(-n >1 由串行改为并行,CLI/工具超时放宽) - 发型红线 skip 词扩充("发型可以改变"等 7 个触发词) - 多图同父节点下载按钮漏补修复 - DOM 节点移动/删除后的按钮兜底 - 文本兜底 row 布局 · 版本对照矩阵更新(README 中/英、INSTALL、CHANGELOG) · 安装 · 方式一(DSH 应用内):插件市场搜索 VisionForge → 安装 · 方式二(一句话):请按 的 INSTALL.md 安装并配置 VisionForge 插件 npm:@lr611/visionforge@0.2.1(latest)
v0.1.92026-10-02
v0.1.9 — 自研重写版:读图/生图/编辑三工具 + 动态引擎翻译器 + 提示词增强器
v0.1.82026-10-02
v0.1.8 — modlens 分叉版(VisionForge 初版,基于上游 modlens 3.26.3),已发布 npm 0.1.8
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
VisionForge 给 DeepSeek Harness 装上「眼睛」和「画笔」:视觉理解 + 图片生成 + 图片编辑,一个插件搞定。 🌐 English | 中文 VisionForge 基于开源视觉插件 liustack/modlens(MIT)深度改造而来:接入千问(Qwen)引擎、新增图片生成与编辑能力、内置图形化设置卡片、支持官方 / 插件双解析优先级调度。改造点全部保留原插件的轻量架构——在 DSH 上只是一个插件目录,卸载即删除,不修改任何 DSH 官方组件,不影响原生功能。 适配环境:DSH Desktop v2.0.17 / DSH harness 0.2.0-rc.2(2026-10 实测)。DSH 大版本更新可能改变插件接口,升级后请重新验证。 桌面端说明:插件只与 harness 版本相关——官方桌面端与第三方桌面端只要 harness 版本相同,对插件功能无实质差异(工具注册、图片预览 / 放大 / 下载等行为一致);但推荐使用官方 DSH Desktop,第三方桌面端不受上游官方支持。
展开完整文档(README 剩余 1 节)
VisionForge

给 DeepSeek Harness 装上「眼睛」和「画笔」:视觉理解 + 图片生成 + 图片编辑,一个插件搞定。

🌐 English | 中文

VisionForge 基于开源视觉插件 liustack/modlens(MIT)深度改造而来:接入千问(Qwen)引擎、新增图片生成与编辑能力、内置图形化设置卡片、支持官方 / 插件双解析优先级调度。改造点全部保留原插件的轻量架构——在 DSH 上只是一个插件目录,卸载即删除,不修改任何 DSH 官方组件,不影响原生功能。

适配环境:DSH Desktop v2.0.17 / DSH harness 0.2.0-rc.2(2026-10 实测)。DSH 大版本更新可能改变插件接口,升级后请重新验证。

桌面端说明:插件只与 harness 版本相关——官方桌面端与第三方桌面端只要 harness 版本相同,对插件功能无实质差异(工具注册、图片预览 / 放大 / 下载等行为一致);但推荐使用官方 DSH Desktop,第三方桌面端不受上游官方支持。

插件版本 × DSH harness 对照

| 插件版本 | 发布日 | 适配 DSH harness | 适配 DSH Desktop | 说明 |
| 0.1.8 及更早 | ≤ 2026-09-27 | harness 0.1.x 早期 | — | 基于 liustack/modlens 3.26.3 的分叉/桥接版(品牌化 + 初步集成) |
| 0.1.9 | 2026-09-28 | harness 0.1.7-rc.1 | — | 连接层重写第一版(约 90% 自研,保留上游致谢),功能基线 |
| 0.1.10 | 2026-09-30 | harness 0.1.7 系列(-rc.1 / -rc.2) | v2.0.14(2026-09 实测) | 0.1.9 增强版:内容合规文档、设置卡片增强、上架准备 |
| 0.2.1(当前) | 2026-10-02 | harness 0.2.0-rc.2(2026-10 实测);兼容 0.1.7 系列 | v2.0.17(2026-10 实测) | 0.1.10 增强版:提示词 100 字门槛 + 六维检测强化 + 细节写作指南 + 多图并行不超时等 5-bug 修复 |

安装层面的兼容范围(npm peerDependencies):@deepseek-ai/dsh-client-ui-primitives 允许 >=0.0.1-rc.1 <0.1.0 || >=0.1.0-rc.1 <0.2.0-0 || >=0.2.0-0 <0.3.0-0(即 harness 0.1.x 与 0.2.x 系列均可安装),上表为实测版本。

功能一览

| 能力 | 说明 |
| 🖼️ 粘贴即读 | 官方视觉模型下图片粘贴进输入框原生预览;纯文本模型下由插件接管转成本地路径并解析,两种模式都无需手动复制路径 |
| 🔭 多提供商视觉引擎 | Qwen / OpenAI(任意 OpenAI 兼容端点)/ Anthropic / Gemini / Antigravity / Claude / Kimi,自动组成故障转移链,一个密钥失败自动轮换下一个 |
| 🎨 图片生成 | visionforge_generate_image:文字描述生成图片(Qwen-Image / GLM-Image),支持 1–6 张、多种尺寸 |
| ✏️ 图片编辑 | visionforge_edit_image:换装、换背景、多图融合、改表情(Qwen-Image edit),支持 1–3 张输入、批量输出变体(每张不同,绝不重复) |
| 🔍 图片放大 | 对话内生成的图片以90px 缩略图呈现,点击图片本体直接用电脑系统图片查看器打开缓存位置的原图放大——不弹 DSH 侧边栏 |
| ⬇️ 一键下载 | 点击「保存图片 N」把缓存图复制到 D 盘根目录(无 D 盘则用户目录 VisionForge 文件夹),并在资源管理器中自动选中刚保存的文件;同样不经过侧边栏 |
| ⚖️ 解析优先级 | 官方优先:官方视觉模型能看图时先解析,不行才走插件;插件优先:始终先用你配置的提供商密钥,全部失败才试官方 |
| ⚙️ 设置卡片 | DSH 设置页内置「VisionForge 配置」卡片,引擎 / 密钥 / 接口 / 模型 / 优先级全部由你自己填写;密钥保存后显示 •••••• 掩码,不写死在代码里;改动内容时保存按钮高亮,保存成功后恢复灰色 |
| 🧩 引擎翻译器(自定义引擎) | 内置引擎之外的任意厂商(Google Gemini、Imagen、OpenAI 兼容网关等)无需改代码即可接入:设置卡片「添加 / 编辑自定义引擎」或 visionforge config add-engine。名称自动规范化并带护栏,接口地址自动识别协议族,读图 / 生图 / 编辑按模型级能力声明 |
| 🎨 画质与提示词增强 | 未指定画质时:支持 2K 的引擎(Qwen / Imagen / Gemini)默认 2K(2560×1440),不支持 2K 的引擎(GLM)默认其最大分辨率(2048×2048);支持 4K / 2.5K / 2K / 1080P 分辨率词表,超引擎上限自动降级并说明。图生图自动追加保护性约束(保持面部特征、肢体自然、不加水印),用户明确改某项时自动跳过对应约束,可关 |
| 🗂️ 统一目录 | 生成图缓存、粘贴原图缓存、下载目录全部收敛固定,不散落在系统临时目录 |
| 🧹 缓存清理 | 生成图与粘贴缓存超过 3 天自动过期清理(启动时执行);已下载的永久副本不受影响 |
| 🔗 本地回环服务 | 预览 / 放大 / 下载走本机固定候选端口(45999/46999/47999/48999)loopback 路由,不依赖提供商的临时 OSS 链接(24h 失效),重启 DSH 后旧消息的图仍可预览、放大、下载 |

安装

方式一:npm 安装(推荐)

npx -y @deepseek-ai/dsh plugin --profile desktop add @lr611/visionforge

安装后进入 DSH 设置 → 内置插件 → VisionForge 配置 卡片填写引擎与密钥,完全重启 DSH Desktop 生效。
若本机已安装旧版 @liustack/modlens,请先移除再安装本包,避免两套插件同时注册同名工具:
npx -y @deepseek-ai/dsh plugin --profile desktop remove @liustack/modlens

方式二:把安装交给你的 AI(不熟悉命令行的用户)

把下面这句话发给你的 AI 助手(DSH 内的助手,或任何能访问本机终端 / 文件的 AI):

按 https://github.com/LR611415/visionforge 的 INSTALL.md 安装并配置 visionforge 插件,完成后运行体检(doctor)并把结果告诉我。

AI 会按 INSTALL.md 的步骤执行:npm 一键安装(或本地复制兜底)→ 配置引擎(可跳过,跳过则随时可去设置卡片补填)→ doctor 体检 → 报告结果。支持 Skill 的 AI 环境可直接加载项目内 skills/visionforge/SKILL.md。

方式三:本地源码复制兜底(离线 / 未发布场景)

见仓库 INSTALL.md 的 Path B:把 dsh/、src/、skills/、cordis.patch.yml、package.json 复制到 DSH 插件安装目录并 npm install。

历史版本:下载与安装

当前版本为 0.2.1。需要回到旧版本(如 v0.1.10 适配 harness 0.1.7 系列)时,两种方式任选:

A. 免下载压缩包(推荐)——DSH CLI 直接指定版本安装

1. 先确认 profile 名(一般为 desktop): Get-ChildItem "$env:USERPROFILE\.dsh\profiles" -Directory | Select-Object -ExpandProperty Name

2. 指定版本安装(<profile> 换成上一步查到的名字):
npx -y @deepseek-ai/dsh plugin --profile desktop add @lr611/visionforge@0.1.10
npx -y @deepseek-ai/dsh plugin --profile desktop add @lr611/visionforge@0.1.9
npx -y @deepseek-ai/dsh plugin --profile desktop add @lr611/visionforge@0.1.8

3. 完全退出并重启 DSH。切回最新版:add @lr611/visionforge@0.2.1。

B. 压缩包手动安装(离线 / 想要源码快照)

1. 下载源码压缩包(GitHub Releases → Assets,或直接链接,v0.1.9 / v0.1.8 同理换 tag 名): https://github.com/LR611415/visionforge/archive/refs/tags/v0.1.10.zip

2. 解压得到 visionforge-0.1.10/ 文件夹
3. 若插件未在 DSH 声明过,先执行一次 npx -y @deepseek-ai/dsh plugin --profile desktop add @lr611/visionforge
4. 把解压文件夹里面的内容整体覆盖到(先备份原目录): %USERPROFILE%\.dsh\profiles\desktop\node_modules\@lr611\visionforge\
5. 完全退出并重启 DSH

⚠️ 历史版本必须与 harness 匹配:见上文「插件版本 × DSH harness 对照」表。在 harness 0.2.0-rc.2 上直接装 v0.1.10 会因 peerDependencies 不兼容而加载失败——跑历史版本前,先把桌面端 / harness 退回对照表对应版本。

快速开始

1. 配引擎:DSH 设置 → 内置插件 → VisionForge 配置 → 选择引擎(如 Qwen)→ 填入 API 密钥、接口地址、模型 → 保存(密钥框显示 •••••• 即保存成功)。
2. 看图:把图片复制 / 粘贴进输入框——官方视觉模型下显示原生预览,直接发送即可解析;插件优先时会转路径交给你的提供商密钥解析。
3. 生图:对话里说"生成一张田间的稻草人",模型调用 visionforge_generate_image,对话内直接出现 90px 缩略图,点击图片用系统图片查看器放大,点「保存图片 N」下载到 D 盘根目录。
4. 改图:粘贴 1–3 张图,说"把女生的衣服换成白色 JK 裙",模型调用 visionforge_edit_image 完成编辑,同样带预览与下载。

自定义引擎(引擎翻译器)

内置引擎之外,你可以添加任意厂商引擎(如 Google Gemini、Imagen、自定义 OpenAI 兼容网关),无需改代码即可读图、生图、编辑。图片怎么传给引擎由「协议族」自动决定——你不需要知道 image_url 与 inline_data 的区别。

在设置卡片添加

1. DSH 设置 → VisionForge 配置卡片 → 底部「+ 添加 / 编辑自定义引擎」。
2. 填:引擎名称(自动规范为小写 a-z0-9._-,与内置引擎重名会被拒绝,拼写相近会提示)、显示名(可选)、接口地址(粘贴后自动按域名预填读图协议族)、读图协议族、生图协议族、API 密钥(可留空稍后补)、视觉模型、生图模型(填了才启用生图)。
3. 保存后引擎会出现在顶部引擎下拉中,可设为默认引擎参与解析。

命令行添加

读图 + 生图(Google Gemini 示例)
visionforge config add-engine google \
--base-url https://generativelanguage.googleapis.com \
--display-name "Google Gemini" \
--read-family gemini --gen-family chat-native \
--model gemini-3.1 --gen-model imagen-4.0

visionforge config list-custom # 查看已添加的自定义引擎 visionforge config remove-engine google # 删除 visionforge config test google # 用 1×1 占位图实测连通性(花极少配额)

密钥与模型可稍后在设置卡片或 visionforge config set custom.<name>.apiKey 补填。

协议族(决定图片上传格式)

| 协议族 | 图片格式 | 适用 |
| openai-compatible(默认兜底) | image_url + data URI | OpenAI 兼容网关、千问、GLM、月之暗面、DeepSeek 等约 90% 厂商 |
| anthropic | image + source base64 块 | Anthropic / Claude 兼容端点 |
| gemini | inline_data(远程图自动拉回 base64) | Google Gemini |
| raw-base64 | 私有端点直接放 base64 字段 | 自定义私有网关 |

生图协议族:dashscope-image(Qwen-Image 原生)、openai-image(/images/generations)、chat-native(Gemini 多模态生成)、google-imagen(Imagen :predict / :editImage)。尺寸格式按协议族自动转换(如 Qwen 要 10241024、OpenAI 要 1024x1024、Imagen 用比例 1:1),不支持的能力会明确报错而非静默。

名称护栏

- 名称自动规范化(大小写 / 空格 / 连字符 / 下划线统一);
- 与内置引擎或已有自定义引擎重名 → 拒绝并说明;
- 与内置引擎拼写相近(编辑距离 ≤ 2,如 qwenx → qwen)→ 提示「你是不是指内置引擎」,不静默改名;
- 接口地址域名可识别协议族并自动预填。

设置卡片配置项

| 字段 | 说明 |
| 引擎 | Qwen / OpenAI / Anthropic / Gemini / Antigravity / Claude / Kimi,或自动(按已配置的密钥自动组成故障转移链,谁可用谁解析) |
| API 密钥 | 由你自己填写,支持英文逗号分隔多 key,鉴权 / 限流 / 配额失败自动轮换;保存后显示 •••••• 掩码,可点选删除 |
| 接口地址 | 该引擎的 Base URL(如千问 AI 平台 OpenAI 兼容端点;Antigravity / Claude / Kimi 为 CLI 引擎无需地址) |
| 模型 | 视觉读图模型(如 qwen3.8-max);切换引擎后下拉列表自动切换为对应引擎的常用模型,也可自定义 |
| 图生图提示词自动增强 | 开启(推荐):简短编辑指令自动追加保护性约束(保持面部特征、肢体自然、不加水印),你明确要求改某项时自动跳过对应约束;关闭则原样发送 |
| 解析优先级 | 官方优先(默认)或 插件优先 |
| 图片输出目录 | 生成图片的缓存目录,默认 D:\VisionForge\out |
| 粘贴转路径 | 智能接管开关(纯文本模型下把粘贴图转成本地路径供插件读取) |

模型候选下拉只列视觉读图模型;生成模型(如 qwen-image-3.0)由生图 / 编辑命令自动调用,不需要在这里选。
引擎为 CLI 类(Antigravity / Claude / Kimi)时,密钥与接口地址无需填写,保存按钮会根据实际改动亮起 / 熄灭。

生成图交互说明

- 画质(默认与分辨率词表):未指定画质时——支持 2K 的引擎(Qwen / Imagen / Gemini)默认 2560×1440(2K);不支持 2K 的引擎(GLM 等边长上限 2048)默认该引擎最大分辨率(2048×2048)。支持口头分辨率词表:4K(3840×2160)、2.5K / 2K(2560×1440)、1080P / 高清(1920×1080)、超清。真 4K 超所有引擎原生上限:Qwen 按总像素上限降为约 2.7K(2728×1536),GLM 按边长上限把 2K 降为 2048×1152,并在结果里给出 sizeNote 说明(不静默降级、不假装 4K)。
- 降级提示(sizeNote):用户明确要求的分辨率引擎不支持时,结果会说明「该引擎不支持需求分辨率 + 最终生成的分辨率 + 支持该分辨率的引擎建议」(如 2K 建议 Qwen / Imagen 4 / Gemini;4K 说明常见引擎暂无原生支持、需外部超分)。
- 图生图提示词自动增强:edit 默认开启——简短指令自动追加保护性约束(严格保持面部特征/五官/发型/身材、肢体与手指自然无畸变、保持构图光影、不添加文字水印);你明确要求改某项(如"换发型")时自动跳过对应约束。可整体关闭(设置卡片开关或 --no-enhance)。
- 缩略图:对话内显示 90px 小图,指向本地 loopback 缓存(不依赖提供商的临时链接)。
- 点击图片:由插件捕获点击 → 请求本机 loopback /visionforge/open → 电脑系统图片查看器打开缓存原图(可放大、缩放、另存);不弹 DSH 侧边栏。
- 保存图片 N:点击后插件拦截该按钮 → 请求本机 loopback /visionforge/download-local → 缓存图复制到 D 盘根目录(无 D 盘则 C:\Users\<你>\VisionForge)+ 资源管理器自动选中刚保存的文件;全程不弹 DSH 侧边栏。
- 宿主自动装饰:链接渲染成按钮时 DSH 会自动加 ↓🌐 图标,属宿主行为,非插件控制。

目录与缓存治理

统一目录(全部固定,可配置)

| 内容 | 位置 | 说明 |
| 生成图缓存 | D:\VisionForge\out(可在设置卡片改 outputDir) | 插件生成的图片,供对话预览 / 放大 / 下载 |
| 粘贴原图缓存 | D:\VisionForge\out\paste | 粘贴接管后写入的本地副本(不再落系统临时目录) |
| 下载永久副本 | D:\ 根目录(无 D 盘则 C:\Users\<你>\VisionForge) | 点击「保存图片 N」后缓存复制到此,永久保留 |
| 插件配置 | C:\Users\<你>\.visionforge\config.json | 引擎、密钥、模型、优先级、输出目录 |

缓存清除机制

- TTL 3 天:生成图缓存与粘贴缓存超过 3 天自动删除(插件启动时清扫)。
- 下载即永久:已下载的副本在 D 盘根目录,不受清理影响。
- 设置卡可视化清理:DSH 设置 → VisionForge →「缓存管理」实时显示输出目录 / 生成图 / 粘贴 / 特征摘要的占用,可一键按 TTL 清理(当前会话生成的图片保留,不影响对话内放大 / 下载)。
- 对话里的预览链接指向缓存;缓存过期后旧消息的缩略图失效属预期行为——重新生成或下载即可。

内容合规与使用边界

VisionForge 提供「真人照片 → 真人照片」的图生图能力。请在使用中遵守下列边界(依据现行法规:民法典第 1019 条、《互联网信息服务深度合成管理规定》、《生成式人工智能服务管理暂行办法》第 12 条、最高法《关于依法审理涉人工智能纠纷案件的意见》(法发〔2026〕10 号)、《人工智能生成合成内容标识办法》)。

三类场景的边界:

| 场景 | 边界 | 说明 |
| 本人照片自用(写真 / 换装 / 场景) | ✅ 允许 | 由你本人确认照片归属即可 |
| 他人照片 | ⚠️ 需授权 | 未经肖像权人同意不得制作、使用、公开其肖像——「制作」本身即侵权,不公开也算;深度合成编辑人脸、人声等生物识别信息需取得被编辑者单独同意 |
| 公众人物冒充 / AI 换脸 / 丑化 / 低俗 / 伪造不实场景 / 未成年人 | ❌ 禁止 | 未经同意生成可识别特定自然人的虚拟数字形象并使用、公开,即构成对姓名权、肖像权等人格权益的侵害(最高法 2026《意见》);AI 换脸做广告已有判赔 80 万的公开判例;未成年人肖像需监护人许可 |

插件与宿主的职责划分:

- 插件(技术护栏,自动化):图生图自动追加保护性约束(保持面部特征 / 肢体自然 / 不加文字水印);不做身份判断——插件无法识别照片里是谁,也不应尝试识别。
- 宿主(判断与拒绝,第一道闸):从对话上下文判断照片归属与授权——本人照片自用放行;他人照片未表明授权则拒绝或要求说明;公众人物冒充、丑化、低俗、伪造不实场景一律拒绝;未成年人要求监护人同意依据。
- 内容标识:生成内容建议自行添加「AI 生成」标识(现行《人工智能生成合成内容标识办法》要求显式标识 + 隐式元数据标识);公开传播前由用户自行确认合规。

注意:对真人照片的身体敏感部位(如胸围 / 腰围等尺寸)进行特征性修改,属于平台审核红线与上述法律边界范畴,插件与引擎均不支持此类请求。请勿尝试通过改写措辞绕过审核——图像引擎对「内衣尺码术语 / 敏感身体部位尺寸」类描述统一拦截,这不是提示词技巧可以绕过的。

边界与卸载(不干扰原生 DSH)

- 作用域严格限定:前端注入的所有行为(点击捕获、按钮拦截、样式、粘贴接管)都以命中插件图片为前提(img[src="/visionforge/image"]、插件渲染的保存按钮);DSH 原生组件、官方消息、其他插件零影响。
- 卸载即干净:移除插件后 DSH 重启即不再注入脚本、不再启动本地服务、端口释放。插件代码全部在插件包内(dsh/index.js、dsh/client.js),不修改任何 DSH 官方文件。
- 先查残留再卸载:npx @lr611/visionforge doctor --uninstall-check 会列出插件在本机留下的全部足迹(配置目录 / 缓存 / 特征摘要 / DSH profile 安装与声明 / 环境变量),对照输出逐项清理即可。
- 可选彻底清理(卸载后): powershell -ExecutionPolicy Bypass -File scripts\uninstall.ps1 # 一键引导式卸载(自动清理 profile 声明/插件目录/配置/缓存,含确认提示)

或手动: Remove-Item -Recurse -Force "C:\Users\<你>\.visionforge" # 插件配置与密钥 Remove-Item -Recurse -Force "D:\VisionForge" # 缓存目录(含已下载副本!先备份要留的)

- 注意:D:\ 根目录下已下载的图片是独立副本,不在 D:\VisionForge 内,卸载后仍保留,需自行确认是否删除。

常见问题

Q:粘贴图片变成 图片 文本? A:你当前选中的模型被判定为纯文本模型,插件接管转成了路径文本(右下角有悬浮缩略图条可预览 / 删除)。切到官方 DeepSeek-V4-Pro / DeepSeek-V4-Flash(或任何声明 image 的视觉模型)即可原生预览。

Q:点击图片没有放大? A:确认已完全重启 DSH 使插件生效;点击的是图片本体(不是旁边的链接文字)。若仍无效,检查 D:\VisionForge\out\click-debug.log 是否有记录:有记录说明点击已到达插件(问题在系统查看器调用),无记录说明点击未到达插件脚本(宿主沙箱限制)。

Q:点击「保存图片 N」没有反应? A:确认按钮文字为「保存图片 N」(不是宿主自动渲染的其他链接)。成功后 D 盘根目录出现文件并自动在资源管理器中选中;若沙箱拒绝 explorer 会自动回退打开目录。

Q:密钥框保存后为什么是空的? A:保存后密钥以 •••••• 掩码显示;若显示为空说明该引擎未配置密钥(或保存失败),重新粘贴密钥再保存。

Q:怎么彻底卸载 VisionForge? A:插件市场 / dsh plugin remove @lr611/visionforge → 完全重启 DSH →(可选)删除 ~/.visionforge 与 D:\VisionForge。卸载后 DSH 原生功能不受任何影响。

Acknowledgements

VisionForge 基于 liustack/modlens(MIT)的图像桥接设计改造而来:在其成熟的视觉解析引擎(OCR / 布局 / 语义证据、失败切换链)之上,独立实现了 Qwen / GLM 生图与编辑、粘贴直读、对话内缩略图预览、系统查看器放大、一键下载与配置卡片等能力。感谢 liustack 的开源贡献。

License

MIT(上游 ModLens 同许可;本改造基于其 MIT 许可源码,可自由修改与分发)。
预览分享卡片长什么样 ↓LR611415/visionforge
分享 · DeepSeek Harness Hub
LR611415/visionforge

给 DeepSeek Harness 装上「眼睛」和「画笔」:视觉理解 + 图片生成 + 图片编辑,一个插件搞定。

这是你的仓库?认领条目

回到顶部