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

生图工作室 aa1355721445-lgtm/dsh-image-studio

DeepSeek Harnessv0.1.7
aa1355721445-lgtm4 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness 生图插件:本地参考库 + 关键词 + 图片/文字转三视图,模型按情境自己判断发什么图

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

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

自动兼容检查未通过:仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add aa1355721445-lgtm/dsh-image-studio
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

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

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

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 00:35:44

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

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

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 90 处,展示前 74 条)
  • 读取本地文件
    lib/index.js:182
    data: readFileSync(f),
  • 发起网络请求
    lib/client.js:61
    function apiGet(path) { return fetch(API + path, { cache: 'no-store' }).then(readJson) }
  • 发起网络请求
    lib/client.js:63
    return fetch(API + path, {
  • 写入剪贴板
    lib/client.js:100
    if (navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(text)
  • 发起网络请求
    lib/client.js:110
    var p = fetch(src, { cache: 'force-cache' }).then(function (res) {
  • 发起网络请求
    lib/client.js:117
    return fetch(src + (src.indexOf('?') >= 0 ? '&' : '?') + 'b64=1', { cache: 'no-store' }).then(readJson).then(function (j) {
  • 写入本地文件
    lib/engine.js:22
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/engine.js:25
    writeFileSync(path.join(dir, file), img.data)
  • 写入本地文件
    lib/engine.js:166
    mkdirSync(dst, { recursive: true })
  • 读取本地文件
    lib/engine.js:169
    if (existsSync(src)) {
  • 写入本地文件
    lib/engine.js:170
    try { renameSync(src, path.join(dst, path.basename(src))) } catch {}
  • 读取本地文件
    lib/http.js:42
    const data = readFileSync(file)
  • 执行外部命令来自配置/变量
    lib/http.js:86
    const child = spawn(cmd, args, { detached: true, stdio: 'ignore' })
  • 执行外部命令来自配置/变量
    lib/http.js:111
    const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'ignore'], windowsHide: false })
  • 读取本地文件
    lib/http.js:128
    dirs: Object.fromEntries(CATEGORIES.map((c) => [c, { path: categoryDir(c), custom: cfg.dirs[c] !== '', exists: existsSync(categoryDir(c)) }])),
  • 读取本地文件
    lib/http.js:221
    if (!existsSync(p)) {
  • 写入本地文件
    lib/http.js:222
    if (body.create === true) mkdirSync(p, { recursive: true })
  • 读取本地文件
    lib/http.js:224
    } else if (!statSync(p).isDirectory()) throw bad(`不是文件夹:${p}`)
  • 写入本地文件
    lib/http.js:226
    mkdirSync(defaultCategoryDir(c), { recursive: true })
  • 读取本地文件
    lib/http.js:258
    if (!target || !existsSync(target)) throw bad('要打开的位置不存在', 404)
  • 读取本地文件
    lib/http.js:275
    if (!abs.startsWith(outputsRoot()) || !existsSync(abs)) throw bad('图片文件不见了', 404)
  • 读取本地文件
    lib/library.js:82
    const parsed = JSON.parse(readFileSync(path.join(dir, META), 'utf8'))
  • 写入本地文件
    lib/library.js:92
    writeFileSync(tmp, `${JSON.stringify(meta, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/library.js:93
    renameSync(tmp, file)
  • 读取本地文件
    lib/library.js:112
    const st = statSync(path.join(dir, file))
  • 读取本地文件
    lib/library.js:123
    try { files = readdirSync(dir).filter((f) => !f.startsWith('.') && isImage(f)) } catch {}
  • 写入本地文件
    lib/library.js:175
    mkdirSync(root, { recursive: true })
  • 读取本地文件
    lib/library.js:176
    names = readdirSync(root, { withFileTypes: true })
  • 读取本地文件
    lib/library.js:234
    while (existsSync(path.join(root, id))) id = `${safeName(entry.name)}-${n++}`
  • 写入本地文件
    lib/library.js:236
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/library.js:237
    renameSync(path.join(root, entry.file), path.join(dir, entry.file))
  • 写入本地文件
    lib/library.js:259
    mkdirSync(root, { recursive: true })
  • 读取本地文件
    lib/library.js:263
    while (existsSync(path.join(root, id))) id = `${base}-${n++}`
  • 删除本地文件递归
    lib/library.js:348
    rmSync(src, { recursive: true, force: true })
  • 写入本地文件
    lib/presets.js:121
    mkdirSync(studioRoot(), { recursive: true })
  • 写入本地文件
    lib/presets.js:123
    writeFileSync(tmp, `${JSON.stringify(next, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/presets.js:124
    renameSync(tmp, presetsPath())
  • 读取本地文件
    lib/presets.js:130
    try { raw = readFileSync(presetsPath(), 'utf8') } catch {
  • 读取本地文件
    lib/sheets.js:116
    try { return JSON.parse(readFileSync(path.join(dir, 'meta.json'), 'utf8')) } catch {
  • 读取本地文件
    lib/sheets.js:123
    return meta.sources.map((f) => path.join(importDir(importId), f)).filter((p) => existsSync(p))
  • 读取本地文件
    lib/sheets.js:130
    return existsSync(p) ? p : null
  • 读取本地文件
    lib/sheets.js:136
    try { names = readdirSync(stagingRoot()) } catch { return }
  • 删除本地文件递归
    lib/sheets.js:139
    try { if (Date.now() - statSync(p).mtimeMs > maxAgeMs) rmSync(p, { recursive: true, force: true }) } catch {}
  • 读取本地文件
    lib/sheets.js:139
    try { if (Date.now() - statSync(p).mtimeMs > maxAgeMs) rmSync(p, { recursive: true, force: true }) } catch {}
  • 写入本地文件
    lib/sheets.js:174
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/sheets.js:180
    writeFileSync(path.join(dir, name), f.data)
  • 写入本地文件
    lib/sheets.js:184
    writeFileSync(path.join(dir, 'meta.json'), JSON.stringify({ category: o.category, hint, sources, createdAt: new Date().toISOString() }), 'utf8')
  • 写入本地文件
    lib/sheets.js:226
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/sheets.js:227
    writeFileSync(path.join(dir, 'meta.json'), JSON.stringify({ category: o.category, mode: 'text', text, name, hint, sources: [], createdAt: new Date().t
  • 读取本地文件
    lib/sheets.js:281
    if (!rel || !existsSync(outputAbs(rel))) throw Object.assign(new Error('三视图文件不见了,重新生成一次'), { status: 404 })
  • 删除本地文件递归
    lib/sheets.js:309
    try { rmSync(importDir(importId), { recursive: true, force: true }) } catch {}
  • 读取本地文件
    lib/store.js:175
    const raw = readFileSync(configPath(), 'utf8')
  • 写入本地文件
    lib/store.js:186
    mkdirSync(studioRoot(), { recursive: true })
  • 写入本地文件
    lib/store.js:188
    writeFileSync(tmp, `${JSON.stringify(next, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/store.js:189
    renameSync(tmp, configPath())
  • 写入本地文件
    lib/store.js:215
    try { mkdirSync(defaultCategoryDir(c), { recursive: true }) } catch {}
  • 写入本地文件
    lib/store.js:217
    try { mkdirSync(outputsRoot(), { recursive: true }) } catch {}
  • 写入本地文件
    lib/store.js:224
    mkdirSync(studioRoot(), { recursive: true })
  • 读取本地文件
    lib/store.js:232
    try { raw = readFileSync(historyPath(), 'utf8') } catch { return [] }
  • 读取本地文件
    lib/store.js:252
    if (!existsSync(historyPath())) return
  • 读取本地文件
    lib/compose.js:45
    if (existsSync(p)) return { label: `上一张生成图(${s})`, absPath: p }
  • 读取本地文件
    lib/compose.js:47
    if (path.isAbsolute(s) && existsSync(s) && / (png|jpe?g|webp|gif)$/i.test(s)) {
  • 读取本地文件
    lib/providers.js:81
    const buf = await readFile(absPath)
  • 发起网络请求
    lib/providers.js:112
    const res = await fetch(url, { signal: withTimeout(signal, 120_000) })
  • 发起网络请求
    lib/providers.js:151
    res = await fetch(`${base}/tasks`, {
  • 发起网络请求
    lib/providers.js:187
    res = await fetch(`${base}/tasks/${encodeURIComponent(taskId)}`, { headers, signal: withTimeout(signal, 90_000) })
  • 发起网络请求
    lib/providers.js:257
    res = await fetch(`${base}/images/generations`, {
  • 读取本地文件
    lib/providers.js:272
    const buf = await readFile(p)
  • 发起网络请求
    lib/providers.js:276
    res = await fetch(`${base}/images/edits`, { method: 'POST', headers, body: form, signal: timeout })
  • 发起网络请求
    lib/providers.js:310
    res = await fetch(`${base}/models`, { headers: authHeaders(cfg), signal: withTimeout(signal, 20_000) })
  • 读取本地文件
    lib/vision.js:79
    const data = await readFile(p)
  • 发起网络请求
    lib/vision.js:177
    const res = await fetch(url, {
  • 读取本地文件
    lib/schedule-link.js:20
    try { return existsSync(file) ? JSON.parse(readFileSync(file, 'utf8')) : null } catch { return null }
  • 读取本地文件
    lib/schedule-link.js:20
    try { return existsSync(file) ? JSON.parse(readFileSync(file, 'utf8')) : null } catch { return null }
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-image-studio · 生图工作室 给 DeepSeek Harness 加一个会「看场合发图」的生图能力:本地四个参考库(人物 / 服饰 / 场景 / 道具),模型判断该出图时,插件按画面描述把对应的参考图组合起来,一起交给生图 API,保证角色和设定一致。 它做了什么 | 部分 | 说明 | | image_generate 工具 | 模型调用:prompt(画面)+ 关键词(situation / expression / pose / shot / light)+ 库条目(characters / outfits / scene / props)→ 组合参考图 → 生图 → 存本地,聊天里显示成图片卡片 | | image_library 工具 | 模型调用:库很大、系统提示里的目录没列全时,按关键词或 id 查条目(含人设、神态特点、情境穿搭) | | 系统提示注入 | 「什么时候发图」三档策略 + 自定义规则 + 主动发图冷却 + 关键词清单 + 参考库目录 | | 设置 → 生图工作室 | 素材库(含「从图片导入」)、关键词、试生成、生成记录、设置 | 安装 需要:DeepSeek Harness 桌面版,以及一个生图接口(65535 的异步任务接口,或任何 OpenAI 兼容的 /v1/images 接口)。
展开完整文档(README 剩余 1 节)
dsh-image-studio · 生图工作室

给 DeepSeek Harness 加一个会「看场合发图」的生图能力:本地四个参考库(人物 / 服饰 / 场景 / 道具),模型判断该出图时,插件按画面描述把对应的参考图组合起来,一起交给生图 API,保证角色和设定一致。

它做了什么

| 部分 | 说明 |
| image_generate 工具 | 模型调用:prompt(画面)+ 关键词(situation / expression / pose / shot / light)+ 库条目(characters / outfits / scene / props)→ 组合参考图 → 生图 → 存本地,聊天里显示成图片卡片 |
| image_library 工具 | 模型调用:库很大、系统提示里的目录没列全时,按关键词或 id 查条目(含人设、神态特点、情境穿搭) |
| 系统提示注入 | 「什么时候发图」三档策略 + 自定义规则 + 主动发图冷却 + 关键词清单 + 参考库目录 |
| 设置 → 生图工作室 | 素材库(含「从图片导入」)、关键词、试生成、生成记录、设置 |

安装

需要:DeepSeek Harness 桌面版,以及一个生图接口(65535 的异步任务接口,或任何 OpenAI 兼容的 /v1/images 接口)。

方式一:在 DSH 里装(推荐)

1. 打开 DSH 侧栏的 插件 → 添加插件(或点箭头选「安装第三方插件」)。
2. 把本仓库地址粘进输入框,点 安装:

https://github.com/aa1355721445-lgtm/dsh-image-studio

3. 装好后点 立即启用。设置里没出现「生图工作室」的话,完全退出 DSH 再打开一次。

方式二:命令行

先完全退出 DSH(托盘里也退出),然后在 PowerShell 里:

dsh plugin --profile desktop add https://github.com/aa1355721445-lgtm/dsh-image-studio

dsh 不在 PATH 上时,用 DSH 安装目录里的完整路径:& "<DSH 安装目录>\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add https://github.com/aa1355721445-lgtm/dsh-image-studio。

升级:DSH 里第三方插件通过「卸载 → 重新安装」升级;素材库、关键词和配置都存在 <DSH_HOME>\image-studio\,卸载不会删掉。

本地开发:git clone 下来后用 dsh plugin --profile desktop add link:<克隆目录> 安装,改代码直接生效(宿主端改动需重启 DSH,只改 lib/client.js 刷新页面即可)。

第一次用

1. 打开 设置 → 生图工作室 → 设置,选接口类型、填 Base URL 和 API Key,点「测试连接」。
2. 「识图」默认用 DSH 自带的看图模型(如 deepseek-flash),不用另填 Key;没有的话可以换成 OpenAI 兼容接口。
3. 到 素材库,顶部的「添加」区写一句描述(用文字生成)或者丢几张图(从图片生成三视图),建几个人物、服饰、场景,就可以在对话里让模型出图了。
4. 「关键词」里自带一套默认情境,其中的场景 / 服饰名(卧室、居家针织服等)只是例子,改成你库里实际有的名字即可;库里没有时会只按文字描述。

添加素材(v0.5)

素材库每个分类顶部都有「添加人物 / 服饰 / 场景 / 道具」区,AI 生成放在最前面:

| 方式 | 怎么用 | 结果 |
| 用文字生成(推荐) | 在框里写几句描述,点「生成」或 Ctrl + Enter | 扩写成完整设定(名字、标签、外观描述),再画一张三视图 / 设定图 |
| 从图片生成三视图 | 把 1–4 张图拖进来或点击选择 | 识别外观写好描述,再画一张标准三视图 |
| 手动新建 | 「想自己填?手动新建」或网格里的「手动新建」卡片 | 自己填名字、描述,上传参考图 |

- 把图片拖到素材库页面的任何地方,也会直接开始「从图片生成」;
- 生成完都会停在「确认」这一步,名字、描述可以先改,不满意可以写要求重画,确认后才存进库;
- 进了手动新建也不用退回去:页面顶部可以把已经填的描述、加的图直接交给 AI 生成;
- 不常用的话点「收起」,会缩成一行三个按钮(记在本机浏览器里)。

参考库

默认目录在 <DSH_HOME>\image-studio\library\{characters,outfits,scenes,props},每个库都能在设置页单独改到别处(比如你已有的素材文件夹)。目录约定对手工整理也友好:

人物库目录\
小鱼\ ← 一个子文件夹 = 一个条目 entry.json ← 名字、别名、标签、外观描述、人设、默认服饰、封面(设置页会自动写) front.png side.png ... 阿星.png ← 散图也算一条(名字 = 文件名),在设置页编辑时会自动收进同名文件夹

- 外观描述会写进生图提示词;人设只给对话模型看,不会发给生图 API。
- 第一张(封面)会被优先当作参考图。人物可以设一套默认服饰。
- 设置页里的「删除」是挪进 image-studio\.trash,不做硬删除。

关键词(v0.2)

为了不让每张图都照抄参考图的姿势和表情,神态、动作、取景交给文字决定。模型先判断角色此刻的状态,再填关键词名字,插件把它展开成具体描写:

| 分组 | 例子 | 说明 |
| 情境 situation | 在家休息、睡前、刚睡醒、工作学习、外出 | 一组搭配:自带场景、默认服饰、光线和氛围描写 |
| 神态 expression | 开心、害羞、困倦、委屈、得意 | 按对话里的心情选 |
| 动作 pose | 抱膝坐、趴着、托腮、伸懒腰 | |
| 镜头 shot | 自拍、近景、全身、俯视、第一人称 | |
| 光线 light | 午后暖阳、夜晚台灯、黄昏逆光 | 不填时用情境的默认光线 |
关键词存在 image-studio\presets.json,第一次运行写入一套默认值,在设置页「关键词」里增删改。没收录的词也能用,会原样当描述。

人物条目多了两项:神态特点(如「开心时尾巴会摇」,会写进提示词)和情境穿搭(在家穿什么、上班穿什么)。服饰的选择顺序:

显式指定 > 人物的情境穿搭 > 情境默认服饰 > 场景默认服饰 > 人物默认服饰

从图片导入 / 三视图(v0.2)

素材库顶部「从图片生成三视图」,丢 1–4 张图进去:

1. 识图:整理出名字、别名、标签和外观描述(只写长相 / 设计,不写表情和姿势)。默认用 DSH 自带的看图模型(deepseek-flash),不用另填 Key;也可以在设置里换成任意 OpenAI 兼容接口。
2. 生成三视图:以原图为参考画一张标准设定图——人物:正 / 侧 / 背三视图,中性 A 字站姿、平静表情、白底;服饰:穿在无脸素体人台上的正 / 侧 / 背三视图(不带模特长相);道具:正 / 侧 / 背 + 45° 斜侧;场景:主视角全景 + 反向视角 + 俯视布局的设定图(去掉人物)。
3. 确认入库:结果都能改,不满意可以写点要求重新生成;存成新条目或加到已有条目,三视图设为封面。

已有条目在编辑页也能「生成三视图」(以封面为参考)和「识别补全」描述与标签。拿三视图当参考,生图时更不容易照抄某个姿势。

文字生成(v0.3)

素材库顶部「用文字生成」的框里写一句话(或在导入面板切到「用文字描述」),就能生成新素材:

1. 扩写:模型把描述扩写成适合生图的详细外观描述(你提到的点一个不改,没提到的合理补全),并起好名字、标签。用的是设置里「识图」那条通道,纯文字任务用 DSH 里任意模型都行。
2. 画三视图:没有参考图,按描述原创设计——人物是 A 字站姿三视图,服饰穿在素体人台上,道具三视图加斜侧,场景是设定图;提示词里同时带上扩写结果和你的原话,原话里的要求必须满足。
3. 确认入库:和图片导入一样可以改、可以写要求重新画;生图失败时也能先存一个只有文字描述的条目,之后再补图。

跟着全天日程穿衣服(v0.4)

同时装了每日日程插件 dsh-daily-schedule 并打开了它的「联动生图工作室 → 穿搭」时,日程里每一段都记着她穿什么。生图时人物是日程里的「她」、又没指定服饰,就直接沿用她此刻那一段的穿着:

- 库里有的那套(如「JK短裙」)作为服饰参考图,日程里写的细节(「外面加了件开衫」)写进【搭配】;
- 库里没有的(如「睡衣」)只按文字描述,不再套默认服饰;
- 这次指定了场景、而且和日程此刻的场景不同(画的不是「现在」),或显式指定了服饰,就不跟;
- 只读日程插件的数据文件(.dsh\daily-schedule\),没装、没生成今天的日程都不影响出图。

设置 → 参考图组合 →「跟着『全天日程』穿衣服」可以关掉。

组合规则

一次出图时:

1. 解析模型给的条目(id、名字、别名都认);打开「自动识别」时,画面描述里提到的库名字也会被带上;
2. 服饰没指定时按「日程此刻的穿着 > 人物的情境穿搭 > 情境默认 > 场景默认 > 人物默认」自动搭配;
3. 按优先级挑参考图:上一张生成图(extra_images)> 人物 > 服饰 > 场景 > 道具,总数不超过上限(默认 8);
4. 给每张参考图编号,写一段「图 N 是什么、怎么用」拼进提示词,例如:

【画面】窝在床上玩手机【情境】在家休息:放松慵懒的居家氛围,周围有生活感的小物件【神态】脸颊泛起红晕,眼神躲闪、微微低头,嘴角含着不好意思的笑【镜头】手机自拍视角:人物一只手臂伸向镜头举着手机(手机在画面外),轻微俯拍【光线氛围】午后温暖的阳光从窗户斜照进来,有柔和的光斑,整体暖色调【人物神态特点】小鱼:开心时尾巴会左右摇摆

【参考图说明(按上传顺序编号)】图1:人物「小鱼」——只用来确定长相:脸型五官、发型发色、瞳色、体型比例和标志性特征。参考图里的姿势、表情、视角和背景都不要照搬。
图2:服饰「睡衣」——只参考服装设计(款式、颜色、材质、细节),穿在「小鱼」身上,随动作自然起褶变形。
图3:场景「卧室」——只参考空间、陈设、配色与风格;镜头角度和取景按上面的描述重新安排。

要求:画一张全新的画面……构图、视角、景别、姿势、动作、表情……一律按上面的文字重新安排,不要沿用任何一张参考图里的站姿、坐姿、表情或取景。

参考图默认「只还原长相和服装设计」:说明里写清每张图只取什么,姿势、表情、视角、构图按文字重新安排(设置里可以关掉,改回严格贴近参考图)。实际发出去的提示词在「生成记录」和「试生成」里都能看到。

接口

- 65535 原生异步任务(默认):POST /v1/tasks 提交,GET /v1/tasks/{id} 轮询;参考图以 data URI 放进 input.image_urls;带 Idempotency-Key,网络抖动重试不会重复扣费。完成后立刻把结果下载到本地(平台的结果链接有有效期)。超时的任务会记成「等待取回」,可在生成记录里一键取回。
- OpenAI 兼容:无参考图走 /v1/images/generations,有参考图走 /v1/images/edits(multipart)。

API Key 只存在本机 image-studio\config.json,网页上只显示末四位。

数据目录

<DSH_HOME>\image-studio\
config.json 配置 presets.json 关键词 staging\ 导入时暂存的原图(入库后清掉,两天没用自动清理) library\ 四个库的默认目录 outputs\YYYY-MM\ 生成的图片(img-日期-时间-随机.png) history.jsonl 生成记录 .trash\ 删除的素材与图片

开发与自检

node tests/smoke-host.mjs # 宿主半:模拟 ctx + 假 65535 接口,跑组合 / 冷却 / 失败 / HTTP 全流程
node tests/smoke-host-v2.mjs # 关键词 / 情境搭配 / 识图(模拟 DSH 模型 + OpenAI 兼容)/ 导入三视图
node tests/smoke-host-v3.mjs # 文字生成:扩写 / 无参考图三视图 / 失败兜底 / 只存文字条目
node tests/smoke-schedule-link.mjs # 跟着全天日程此刻的穿搭出图
node tests/smoke-client.mjs # 浏览器半:把设置页每个页签、导入各步骤和聊天卡片的各状态渲染一遍
node --check lib/client.js

宿主端(lib/*.js 除 client.js)改了要重启 DSH;只改 lib/client.js 刷新页面即可。

许可

MIT
预览分享卡片长什么样 ↓aa1355721445-lgtm/dsh-image-studio
分享 · DeepSeek Harness Hub
aa1355721445-lgtm/dsh-image-studio

DeepSeek Harness 生图插件:本地参考库 + 关键词 + 图片/文字转三视图,模型按情境自己判断发什么图

这是你的仓库?认领条目

回到顶部