在会话侧栏调用 NovelAI 生成与编辑插画
31.2/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/17 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add siriustl/dsh-novelai-atelier该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · tool
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 21 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 92 处,展示前 83 条)
- 发起网络请求client/api.ts:25
try { return await fetch(url, { credentials: 'same-origin', ...init }) } - 发起网络请求src/core/client.ts:185
dispatcher = this.proxy ? new ProxyAgent(this.proxy) : undefined - 发起网络请求src/core/client.ts:188
response = await fetch(target, opts) - 发起网络请求src/core/client.ts:276
return await this.request('GET', url, init, signal) - 发起网络请求src/core/client.ts:330
const response = await this.request('POST', this.imageUrl + endpoint, { json: payload }, signal) - 读取本地文件src/core/imageInputs.ts:51
if (!existsSync(target) || !statSync(target).isFile()) throw new Error(`Image file does not exist: ${target}`) - 读取本地文件src/core/imageInputs.ts:51
if (!existsSync(target) || !statSync(target).isFile()) throw new Error(`Image file does not exist: ${target}`) - 读取本地文件src/core/imageInputs.ts:52
if (statSync(target).size > MAX_INPUT_BYTES) throw new Error('Input image exceeds the 48 MiB file limit') - 读取本地文件src/core/metadata.ts:37
if (!existsSync(target) || !statSync(target).isFile() || statSync(target).size > 64 * 1024 * 1024) - 读取本地文件src/core/metadata.ts:37
if (!existsSync(target) || !statSync(target).isFile() || statSync(target).size > 64 * 1024 * 1024) - 读取本地文件src/core/metadata.ts:39
const data = readFileSync(target) - 读取本地文件src/core/operations.ts:138
if (!existsSync(path) || !statSync(path).isFile()) throw new Error(`Vibe encoding file does not exist: ${path}`) - 读取本地文件src/core/operations.ts:138
if (!existsSync(path) || !statSync(path).isFile()) throw new Error(`Vibe encoding file does not exist: ${path}`) - 读取本地文件src/core/operations.ts:139
const data = readFileSync(path) - 读取本地文件src/core/operations.ts:177
if (existsSync(receiptPath)) { - 读取本地文件src/core/operations.ts:178
if (statSync(receiptPath).size > 1024 * 1024) throw new Error('Vibe receipt exceeds the size limit') - 读取本地文件src/core/operations.ts:180
try { receipt = JSON.parse(readFileSync(receiptPath, 'utf8')) } catch { throw new Error('Invalid vibe JSON receipt') } - 写入本地文件src/core/preparation.ts:128
mkdirSync(directory, { recursive: true }) - 写入本地文件src/core/preparation.ts:132
writeFileSync(imagePath, result.toPng()) - 写入本地文件src/core/preparation.ts:140
writeFileSync(maskPath, mask.toPng()) - 写入本地文件src/core/preparation.ts:149
writeFileSync(receipt, JSON.stringify({ request, result: response }, null, 2) + '\n', 'utf8') - 读取本地文件src/core/recovery.ts:53
if (!existsSync(path) || !statSync(path).isFile() || !path.toLowerCase().endsWith('.json')) throw new Error('Receipt must be a local .json file') - 读取本地文件src/core/recovery.ts:53
if (!existsSync(path) || !statSync(path).isFile() || !path.toLowerCase().endsWith('.json')) throw new Error('Receipt must be a local .json file') - 读取本地文件src/core/recovery.ts:54
const raw = readFileSync(path) - 读取本地文件src/core/recovery.ts:72
return { path, exists: existsSync(path) && statSync(path).isFile() } - 读取本地文件src/core/recovery.ts:72
return { path, exists: existsSync(path) && statSync(path).isFile() } - 写入本地文件src/core/service.ts:38
writeFileSync(tmp, content) - 写入本地文件src/core/service.ts:43
renameSync(tmp, path) - 删除本地文件src/core/service.ts:55
try { unlinkSync(tmp) } catch { } - 写入本地文件src/core/service.ts:158
mkdirSync(directory, { recursive: true }) - 写入本地文件src/core/service.ts:195
writeFileSync(responsePath, response) - 写入本地文件src/core/service.ts:206
writeFileSync(path, response) - 写入本地文件src/core/service.ts:222
writeFileSync(rawPath, imageBytes) - 删除本地文件src/core/service.ts:254
unlinkSync(responsePath) - 读取本地文件src/core/service.ts:326
return JSON.parse(readFileSync(path, 'utf8')) as Record<string, unknown> - 读取本地文件src/core/specs.ts:24
cached = JSON.parse(readFileSync(base, 'utf8')) as SpecCatalog - 读取本地文件src/workbench/app.ts:41
if (existsSync(path)) return readFileSync(path, 'utf8') - 读取本地文件src/workbench/app.ts:41
if (existsSync(path)) return readFileSync(path, 'utf8') - 写入本地文件src/workbench/assets.ts:20
mkdirSync(this.directory, { recursive: true }) - 读取本地文件src/workbench/assets.ts:66
const [root, source] = await Promise.all([realpath(this.directory), realpath(frozenPath)]) - 读取本地文件src/workbench/assets.ts:69
const info = await stat(source) - 读取本地文件src/workbench/assets.ts:70
if (!info.isFile() || info.size > MAX_ASSET || createHash('sha256').update(readFileSync(source)).digest('hex') !== digest) - 读取本地文件src/workbench/assets.ts:75
if (!existsSync(path)) writeFileSync(path, data) - 写入本地文件src/workbench/assets.ts:75
if (!existsSync(path)) writeFileSync(path, data) - 读取本地文件src/workbench/assets.ts:81
if (!existsSync(source) || !statSync(source).isFile() || statSync(source).size > MAX_ASSET) - 读取本地文件src/workbench/assets.ts:81
if (!existsSync(source) || !statSync(source).isFile() || statSync(source).size > MAX_ASSET) - 写入本地文件src/workbench/assets.ts:107
if (!existsSync(target)) writeFileSync(target, data) - 发起网络请求src/workbench/assistant.ts:341
response = await fetch(endpoint, { - 发起网络请求src/workbench/assistant.ts:578
const result = await this.request(endpoint, apiKey, String(config['model']), messages, { - 读取本地文件src/workbench/backup.ts:73
if (!existsSync(raw)) throw new Error('备份所需文件缺失:' + raw) - 读取本地文件src/workbench/backup.ts:74
const data = readFileSync(raw) - 读取本地文件src/workbench/backup.ts:99
if (!existsSync(value)) return - 写入本地文件src/workbench/backup.ts:176
mkdirSync(directory, { recursive: true }) - 写入本地文件src/workbench/backup.ts:179
writeFileSync(target, zipped) - 读取本地文件src/workbench/backup.ts:187
const raw = readFileSync(path) - 写入本地文件src/workbench/backup.ts:274
mkdirSync(assetsDirectory, { recursive: true }) - 写入本地文件src/workbench/backup.ts:276
mkdirSync(output, { recursive: true }) - 读取本地文件src/workbench/backup.ts:295
if (!existsSync(target)) writeFileSync(target, bytes) - 写入本地文件src/workbench/backup.ts:295
if (!existsSync(target)) writeFileSync(target, bytes) - 执行外部命令来自配置/变量src/workbench/reveal.ts:19
const child = spawn(command, [path], { shell: false, stdio: 'ignore', windowsHide: false }) - 读取本地文件src/workbench/reveal.ts:62
const info = await stat(path) - 读取本地文件src/workbench/reveal.ts:64
const bytes = await readFile(path) - 读取本地文件src/workbench/reveal.ts:74
try { canonical = await realpath(candidate); if (!(await stat(canonical)).isFile()) continue } - 读取本地文件src/workbench/reveal.ts:74
try { canonical = await realpath(candidate); if (!(await stat(canonical)).isFile()) continue } - 写入本地文件src/workbench/settings.ts:23
mkdirSync(this.secretsDir, { recursive: true, mode: 0o700 }) - 写入本地文件src/workbench/settings.ts:24
chmodSync(this.secretsDir, 0o700) - 读取本地文件src/workbench/settings.ts:29
if (create && !existsSync(path)) { - 读取本地文件src/workbench/settings.ts:30
const encrypted = readdirSync(this.secretsDir).some((name) => name.endsWith('.secret') - 读取本地文件src/workbench/settings.ts:31
&& readFileSync(join(this.secretsDir, name), 'utf8').startsWith('NAI-SECRET-V1\n')) - 写入本地文件src/workbench/settings.ts:33
try { writeFileSync(path, randomBytes(32), { flag: 'wx', mode: 0o600 }) } catch (error) { - 读取本地文件src/workbench/settings.ts:37
const key = readFileSync(path) - 写入本地文件src/workbench/settings.ts:39
chmodSync(path, 0o600) - 写入本地文件src/workbench/settings.ts:53
writeFileSync(tmp, envelope, { flag: 'wx', mode: 0o600 }) - 写入本地文件src/workbench/settings.ts:54
try { renameSync(tmp, path) } catch (error) { try { unlinkSync(tmp) } catch { } throw error } - 删除本地文件src/workbench/settings.ts:54
try { renameSync(tmp, path) } catch (error) { try { unlinkSync(tmp) } catch { } throw error } - 读取本地文件src/workbench/settings.ts:60
if (!replaceExisting && existsSync(join(this.secretsDir, reference + '.secret'))) this.secret(reference) - 读取本地文件src/workbench/settings.ts:68
const stored = readFileSync(join(this.secretsDir, reference + '.secret'), 'utf8') - 读取本地文件src/workbench/util.ts:81
return JSON.parse(readFileSync(this.path, 'utf8')) as T - 写入本地文件src/workbench/util.ts:89
mkdirSync(dirname(this.path), { recursive: true }) - 写入本地文件src/workbench/util.ts:91
writeFileSync(tmp, JSON.stringify(value)) - 写入本地文件src/workbench/util.ts:93
renameSync(tmp, this.path) - 删除本地文件src/workbench/util.ts:95
try { unlinkSync(tmp) } catch { } - 读取本地文件src/workbench/util.ts:100
exists(): boolean { return existsSync(this.path) }
扫描于 2026/11/4(0 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-scope@deepseek-ai/dsh-tools@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
面向 DeepSeek Harness 的 NovelAI V5/V4.5 生图插件:内置 15 项 Agent 工具与嵌入式生图工作台
README
由 DeepSeek 最新模型翻译生成DSH NovelAI Atelier
面向 DeepSeek Harness 智能体生态的 NovelAI V5 / V4.5 图像生成工具集与嵌入式工作台插件。
🌟 核心特性
- 🤖 15 项 Agent 原生工具:文生图(nai_generate_image)、全能图像编辑(nai_edit_image:含局部重绘、全图重绘、增强、2倍放大、导演线稿、Vibe编码)、参数回执恢复与检查(nai_image_info)、资料库与草稿管理等,专为大语言模型 Tool Calling 精心设计与压缩。
- 🎨 无缝嵌入式右侧工作台:深度注入 DSH 右侧栏抽屉(sidebarRightTabs),无需额外开启独立 Web 端口或后台服务,与当前 AI 会话实时共享内存草稿与上下文。
- 📚 模块化资料库(Library):支持角色本体定义、形态分支(服装/外形差异化继承)、画师风格混合、负面提示词解耦与例图可视化管理。
- ⏱️ 自动化生图计划(Schedules):支持单次、每日、定时间隔以及固定请求/AI 智能构思的自动化任务队列,内置额度与运行次数安全预算保护。
- 🔒 本地优先与隐私安全:NovelAI Token(pst-...)本机安全加密隔离存储;所有生成图片、元数据与工作台数据严格保存在本地用户目录。
展开完整文档(README 剩余 1 节)
DSH NovelAI Atelier
面向 DeepSeek Harness 智能体生态的 NovelAI V5 / V4.5 图像生成工具集与嵌入式工作台插件。
🌟 核心特性
- 🤖 15 项 Agent 原生工具:文生图(nai_generate_image)、全能图像编辑(nai_edit_image:含局部重绘、全图重绘、增强、2倍放大、导演线稿、Vibe编码)、参数回执恢复与检查(nai_image_info)、资料库与草稿管理等,专为大语言模型 Tool Calling 精心设计与压缩。
- 🎨 无缝嵌入式右侧工作台:深度注入 DSH 右侧栏抽屉(sidebarRightTabs),无需额外开启独立 Web 端口或后台服务,与当前 AI 会话实时共享内存草稿与上下文。
- 📚 模块化资料库(Library):支持角色本体定义、形态分支(服装/外形差异化继承)、画师风格混合、负面提示词解耦与例图可视化管理。
- ⏱️ 自动化生图计划(Schedules):支持单次、每日、定时间隔以及固定请求/AI 智能构思的自动化任务队列,内置额度与运行次数安全预算保护。
- 🔒 本地优先与隐私安全:NovelAI Token(pst-...)本机安全加密隔离存储;所有生成图片、元数据与工作台数据严格保存在本地用户目录。
📦 安装与配置
推荐:桌面客户端 GUI 一键安装
1. 从 Releases 页面 下载最新安装包 dsh-novelai-atelier-0.15.3.tgz 并保存到本地稳定路径。
2. 打开 DeepSeek Harness 左侧「插件」页面,点击「添加插件」。
3. 在「包名或地址」输入安装包的绝对路径(例如 D:\Downloads\dsh-novelai-atelier-0.15.3.tgz),点击安装。
4. 安装完成后点击「立即启用」。
5. 建议完整退出并重新打开 DSH,以保证宿主进程、原生图片依赖与前端模块完全加载生效。
6. 打开右侧抽屉栏的「NovelAI 生图工作台」,在设置中配置你的 NovelAI pst-… 令牌。
命令行(CLI)安装
在桌面客户端自带的 CLI 环境中执行(PowerShell 示例):
& 'D:\Program Files\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop add 'D:\Downloads\dsh-novelai-atelier-0.15.3.tgz'
详细的配置与版本迁移说明请参阅 安装指南 (INSTALL.md)。
🚀 常用生成与协作流程
1. 智能体按需启用
- 普通模式下默认仅加载轻量入口 nai_use_tools,不会占用额外 Context Token;
- 当需要生图或编辑时,AI 自动或手动调用 nai_use_tools({enabled:true}) 挂载完整能力;
- 也可以直接新建「NovelAI Atelier」专属预设模式会话。
2. 文生图与编辑
- 单张文生图:调用 nai_generate_image,默认采用 V5 Full、23 步、Euler Ancestral、Karras 调度、CFG 7,生成完毕直接返回图片路径。
- 图像编辑与重绘:通过 nai_edit_image 完成全图重绘(img2img)、局部重绘(inpaint,白色涂抹重绘)、细节增强(enhance)、2倍无损放大(upscale)或风格提取(encode_vibe)。
- 参数与回执回溯:使用 nai_image_info 的 recover 操作可直接从已生成的 PNG 或回执 JSON 中完美还原所有提示词、Seed、模型参数及参考图哈希。
3. 数据与隐私安全规范
- 默认工作台数据目录:~/.novelai-workbench
- 默认图片保存目录:~/Pictures/NovelAI
- 分发与共享提示:对外分发插件时只需提供官方打出的 .tgz 发布包。请勿将本机的私有工作台目录、凭据目录(secrets/)或整库备份对外共享。从画廊导出的作品原图可能包含提示词、Seed 及 EXIF 元数据,对外公开发布前请注意核对。
🛠️ 本地开发与质量验证
本项目采用严格的工程规范与测试驱动验证:
类型检查
pnpm run typecheck
运行自动化测试(52 文件 / 596 测试用例)
pnpm test
构建客户端与服务端 bundle
pnpm run build
验证包导出与安装包完整性
pnpm run verify:package
📄 开源许可证
本项目基于 MIT License 开源。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
siriustl/dsh-novelai-atelier
在会话侧栏调用 NovelAI 生成与编辑插画
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 4,330已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,636已汉化DSH
72.2
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,349已汉化DSH
71.6
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,311已汉化DSH
71.4
智能体运行框架路由HarnessRouter/harnessrouter
智能体 harness 的统一接口。
★ 3,984已汉化DSH
71.3
这是你的仓库?认领条目