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

MC 模组工坊 GMH13552/dsh-mc-art

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

从描述生成可验证的 Minecraft 模组并自动判定

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

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

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

状态速览

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

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

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

安装清单取自 panel/package.json

展开查看检查明细 ↓

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

✓npm 包dsh-mc-art-panel @ 0.2.9
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/11 22:26:52

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 58 处,展示前 32 条)
  • 写入本地文件
    lib/index.js:33
    async mkdirp(path) { await nodeMkdir(path, { recursive: true }) },
  • 读取本地文件
    lib/index.js:36
    const info = await nodeStat(path)
  • 读取本地文件
    lib/index.js:42
    const entries = await nodeReaddir(path, { withFileTypes: true })
  • 读取本地文件
    lib/index.js:46
    try { const info = await nodeStat(path + '/' + entry.name); size = info.size; version = String(info.mtimeMs) } catch (error) {}
  • 读取本地文件
    lib/index.js:53
    try { return await nodeReadFile(path, 'utf8') } catch (error) { return undefined }
  • 读取本地文件
    lib/index.js:57
    const buffer = await nodeReadFile(path)
  • 写入本地文件
    lib/index.js:63
    await nodeMkdir(nodeDirname(path), { recursive: true })
  • 写入本地文件
    lib/index.js:64
    await nodeWriteFile(path, text, 'utf8')
  • 写入本地文件
    lib/index.js:67
    await nodeMkdir(nodeDirname(path), { recursive: true })
  • 写入本地文件
    lib/index.js:68
    await nodeWriteFile(path, Buffer.from(base64, 'base64'))
  • 删除本地文件
    lib/index.js:70
    async remove(path) { await nodeRm(path, { force: true }) },
  • 写入本地文件
    lib/index.js:72
    await nodeMkdir(nodeDirname(to), { recursive: true })
  • 发起网络请求
    lib/client.js:30
    return fetch('/api/mcart/call', {
  • 读取本地文件
    build.mjs:84
    export const PACKAGE_NAME = JSON.parse(readFileSync(join(HERE, 'package.json'), 'utf8')).name
  • 读取本地文件
    build.mjs:88
    export const PACKAGE_VERSION = JSON.parse(readFileSync(join(HERE, 'package.json'), 'utf8')).version
  • 读取本地文件
    build.mjs:126
    const VERSION = ${JSON.stringify(JSON.parse(readFileSync(join(HERE, 'package.json'), 'utf8')).version)}
  • 读取本地文件
    build.mjs:352
    })(React, host, styles, console, ${JSON.stringify(JSON.parse(readFileSync(join(HERE, 'package.json'), 'utf8')).version)})
  • 读取本地文件
    build.mjs:433
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    build.mjs:438
    const before = readFileSync(full)
  • 写入本地文件
    build.mjs:440
    if (!after.equals(before)) { writeFileSync(full, after); changed += 1 }
  • 执行外部命令固定命令
    build.mjs:450
    const done = spawnSync('git', ['-C', dir, 'rev-parse', 'HEAD'], { encoding: 'utf8' })
  • 删除本地文件递归
    build.mjs:480
    rmSync(to, { recursive: true, force: true })
  • 写入本地文件
    build.mjs:481
    mkdirSync(dirname(to), { recursive: true })
  • 删除本地文件递归
    build.mjs:495
    rmSync(pythonDir, { recursive: true, force: true })
  • 写入本地文件
    build.mjs:496
    mkdirSync(pythonDir, { recursive: true })
  • 写入本地文件
    build.mjs:503
    copyFileSync(from, to)
  • 写入本地文件
    build.mjs:512
    copyFileSync(from, to)
  • 写入本地文件
    build.mjs:529
    writeFileSync(VENDOR_STATE, JSON.stringify(state, null, 2) + '\n')
  • 删除本地文件递归
    build.mjs:643
    rmSync(target, { recursive: true, force: true })
  • 删除本地文件
    build.mjs:697
    rmSync(file, { force: true })
  • 删除本地文件
    build.mjs:705
    try { rmdirSync(dir) } catch (error) { break }
  • 删除本地文件递归
    build.mjs:709
    rmSync(target, { recursive: true, force: true })
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

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

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

功能亮点

  • 从描述生成模组

DeepSeek Harness 面板插件 + 做模组的 skill:从描述到可验证的 Minecraft mod,由游戏自己的 GameTestServer 判定

v0.3.42026-10-28
· dsh-mc-art-panel 0.3.4 · 0.3.4 · 修复——一个预设变量让该模式下的每个会话都崩了 presets/mc-studio/agent.cordis.yml 在 persona 里带了 suffix: Your working directory is {{cwd}}.,又在 prefix 正文里再次引用了同一个变量。当前运行时只为该提示词段注册 provider 和 model,所以渲染系统提示词时抛出 unknown prompt variable "{{cwd}}",整个回合在模型跑起来之前就失败了——会话只显示「处理失败 · 本轮运行失败」。 · 工作目录那句话已删掉,prefix 现在写的是 本会话的工作目录;预设里不再有提示词文本引用未注册的变量。 · tools/gen_preset_patch.mjs --write 重新生成了独立的 desktop-generation.patch.yml 和 panel/cordis.patch.yml 里内嵌的那份,所以发布的包里带着修复。 · 新增校验 preset-vars-test.js(plugin-preset-vars):预设 YAML 和打包补丁里的每个 {{var}} 都必须在 {provider, model} 范围内;--fault 会注入一个未知变量并以 1 退出。 · 注意 智能体的组成在会话创建时就固定了,所以已经失败的会话会一直失败。重启 DSH,然后在该模式下开一个新对话。
v0.3.32026-10-28
· dsh-mc-art-panel 0.3.3 · 0.3.3 第一轮 UI 评审针对设置视图,因为「AI 做的」痕迹在这里最明显:一堆平铺的行,标签列对不齐,没有分组,还有个错别字。 · 改动 — 设置,依据截图评审 · 现在是真的属性网格:固定 88px 标签列,标签右对齐,值从同一轴线开始,提示放在值列下方。路径行不再自带缩进(之前比其他标签偏了约 39px)。 · 分组:参考目录 / 生成 / 命名空间 / 通知 / 文件 — 每组一个 11px/600 的弱化标题,配 1px 细线,不再是一张不分层的列表。 · 是独立视图,不是插入块:设置作为单独页面打开,带一个返回资产列表控件;之前它叠在资产列表上方,把列表和 3D 视口都挤扁了。 · 措辞错误已修:检测行写的是 2242 张截图,实际指贴图 — 现在是 2242 张贴图,数字用等宽字体和表格数字。 · 长路径(设置文件 …)之前被面板边缘裁掉且没有省略号;现在正确截断,完整路径放在 title 里。 · 按钮统一 22px 高;复选框 12×12,1px 边框,选中时是品牌色对勾,并带 :focus-visible。 · 修复 — 地面网格不再透过方块显示 3D 视口在 putImageData 之后用 canvas 2D 描边画地面网格。这会覆盖已渲染的每个像素,于是网格线穿过方块表面 — 看起来就像方块半透明。其实从来不是:光栅化器会拒绝 alpha 低于 0.5 的面,写深度时不混合,所以面是不透明的。 现在网格带深度测试光栅化进颜色/深度缓冲,方块会遮挡它,线条只出现在背景像素上。拾取缓冲仍未改动(网格不可点击)。新增门禁 grid-occlusion-test.js,用两个合成缓冲执行生成的函数,断言更近的遮挡区域内部没有一个像素被染色 — 而 --fault 会删掉深度测试,证明该断言确实会失败。 · 门禁 · ui-test 为这个视图加了行为断言:齿轮能打开它,它不与列表/视口渲染在同一屏,返回资产列表能把列表带回来 — 外加 --fault-settings-back,删掉该按钮的处理函数,让断言变红。 · ui-style-test 加了属性网格、分组标题和复选框的断言。 · 51 项条件,两轮(默认控制台编码和 --encoding gbk):50 绿 / 1 SKIP / 0 红。
v0.3.22026-10-18
· dsh-mc-art-panel 0.3.2 · 0.3.2 这个项目需要的 UI 改造从来不是「做得更好看」,而是「能看见它」。这次发布先写规格,再给一台能看见结果的机器。 · 新增 — 两份文档 · docs/UI-STYLE.md — 一份设计规格,不是情绪板:参照语言是*专业检查器*(Blender 属性面板 / VS Code 面板——扁平、密集、窄、安静),并明确列出反例清单,说明哪些做法让面板看起来像「AI 做的」:卡片套卡片、大圆角、胶囊按钮、渐变、发光、动画、彩色标签、emoji 图标、16px 以上内边距、居中的表单标签。它把数字定死:字号 12/11px,行高 22px,表单行 26px,工具栏 28px,控件 22px,圆角只用 2/3,间距 2/4/6/8,四种交互状态,颜色只用 token。 · docs/CUA-UI-REVIEW.md — 智能体怎么看见这个面板:官方 @deepseek-ai/dsh-experimental-computer-use-cua-driver-mcp 服务商(由 DeepSeek 发布,位于 deepseek-ai/deepseek-harness 的 packages/experimental/…)挂到本地安装的 Cua 驱动上,外加精确的截图/缩放/点击流程和其中的坑(Electron 不暴露 UIA 树;Chromium 输入框只接受前台投递;坐标位于返回截图的像素空间)。 · 变更 — 面板,以截图为准 · 页头:面包屑泄露了位置术语(中央面板),还重复了标签页标题。现在只有一行——只显示路径(等宽 11px,弱化色,超长省略,完整路径放在 title 里)。 · 资源列表:每行两列——左侧是本地化名称,右侧对齐、弱化色的等宽 id——不再是 深渊砖 abyss_bricks 挤在一起。分组标题(方块 · 44)吸顶并带细线,列表填满容器并独立滚动,选中行左侧 2px 竖条改用品牌衍生 token(--mc-brand-bar,品牌色 75% + 文字色 25%),不再显得发灰。 · 工具栏:计数(6 面 · 贴图 1/1)用等宽弱化色放在左侧;重置/手动修改做成图标按钮,带提示和 1px 分隔线;@ 提意见是唯一的主操作,右对齐。 · 3D 视口:相机现在自动适配包围盒,把八个角投影进 88% 安全框(约 12% 边距),为快捷栏预留空间并把内容上移,方块永远不会被裁掉,切换资源、调整视口大小时重新适配。一层淡淡的地面网格和一个小坐标轴指示器给模型一个地面和方向感;选中标签从浮在快捷栏上的标签移到角落的等宽文字。 · 窄宽度:设置里的「使用」按钮被右侧栏裁掉;输入框和按钮组现在换行,不再溢出。 · 修复 — 给出恢复办法,而不是裸报错 · 「宿主已卸载」现在可操作了。反复重建加 HMR 之后,宿主那一半可能处于已释放状态(0 个方法),面板以前只显示这句话,别的什么都没有。现在分两行说明插件宿主没有加载(重建后马上就会这样),以及必须完全退出并重新打开 DSH——技术细节折叠在详情下——并在报告前隔一秒重试一次操作。 · 面板位置确定下来了。启动时右侧栏服务可能比面板晚出现;面板现在会重试迁移,落到右侧栏后移除左/中兜底。ui-test --fault-placement 证明这次重试是承重的(删掉它 → 三条断言变红)。 · 门禁 · 新增 tools/mcart-plugin/ui-style-test.js(plugin-ui-style):对实际发布的 CSS 字符串做 27 条断言——反例清单每一项都必须不存在,每个固定数字都必须存在;三种故障模式返回退出码 1。icon-test 增加了 fit/reset/grid/axis/details/retry/两列行/位置重试的静态断言;ui-test 增加了位置竞争和宿主未加载行为,没有放松任何现有行为断言。 · 51 个条件,两轮(默认控制台编码和 --encoding gbk):50 绿 / 1 SKIP / 0 红。 · 备注 视觉评审是在上一版构建上用 CUA 截图做的;这一批的最终外观由代码、测试和门禁检查,需要刷新一次页面才能看到。
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-mc-art · 从描述到可验证的 Minecraft mod 一个用于 DeepSeek Harness 的 Cordis 面板插件 + 做模组的 skill,外加一个验证闭环,让真实游戏来判定一个 mod 是否正确。 DSH 插件 + 做模组的 skill + 一个裁判。 插件负责看和改,skill 负责流程,裁判是 Mojang 自带的 GameTestServer(无窗口服务端,退出码 = 失败的必要测试数)。 美术引擎在另一个仓库:GMH13552/mc-art (确定性引擎:扫描资源根 / 出证据 / 栅格化 / 度量)。这个仓库不含它的副本 ——同一个东西放两个仓库就会漂移。
展开完整文档(README 剩余 1 节)
dsh-mc-art · 从描述到可验证的 Minecraft mod

一个用于 DeepSeek Harness 的 Cordis 面板插件 + 做模组的 skill,外加一个验证闭环,让真实游戏来判定一个 mod 是否正确。

DSH 插件 + 做模组的 skill + 一个裁判。 插件负责看和改,skill 负责流程,裁判是 Mojang 自带的 GameTestServer(无窗口服务端,退出码 = 失败的必要测试数)。

美术引擎在另一个仓库:GMH13552/mc-art (确定性引擎:扫描资源根 / 出证据 / 栅格化 / 度量)。这个仓库不含它的副本 ——同一个东西放两个仓库就会漂移。

里面有什么

| 路径 | 是什么 |
| skills/mc-mod/ | 做模组的 skill:插件说明书、通用流程(七阶段)、版本矩阵、GameTest 闭环、踩过的坑 |
| tools/mcart-plugin/ | 面板插件(DSH 动态 Cordis 插件)源码 + 加载器 + 门禁 |
| tools/mcart_extract_block.py | 抽取器:把一个方块/物品读成几何 + 贴图 + 表现形态(1.12.2 / 1.18.2 两套规则) |
| tools/mcart_scan_refs.py | 参考扫描:从游戏目录/模组 jar 里列出命名空间与方块 |
| tools/mcmod_gametest.py | 判定工具:跑 GameTestServer、读退出码、解析日志、给裁决;--fault 注入错误断言 |
| fleshland/mod/ | 一个完整可运行的模组骨架(Forge 1.18.2):故意不带资源,只带代码 + 两条 GameTest |
| presets/mc-studio/ | MC 模组工作室模式(agent preset):把面板能力 + 流程 + 裁判包装成一个可选的模式 |
| panel/ | 面板的真包形态:dsh plugin --profile web add 装进 profile,重启就在(不用发射动态插件) |

一、面板(mcart)

一个 Cordis 动态插件,把项目里的资产变成可以看和改的东西:

- 3D 取景框 + 游戏样式的九格物品栏:选中格白框、翻页、名字浮层;没有 3D 可看时把 2D 形式画进取景框(物品只有物品模型时);底边可拖动改高度(140–760 px,双击复位)。
- 物品浏览器:按来源(本项目 / 原版 / 每个模组)、展示形式(方块/工具/盔甲/刷怪蛋/物品)、细分家族筛选,一页 40 格;点一格就放到 3D 里看。
- 像素编辑器:铅笔 / 油漆桶 / 取色 / 橡皮,调色板、不透明度、撤销 24 步,方块可按面编辑;保存走"临时文件 → 校验是 PNG → 才替换原文件",只写项目自己的资源包。
- 结构 / 群系编辑器:按格放置(左键破坏、右键放置),带朝向、撤销与保存。
- @ 提意见:把资产的身份(atlas 引用,或物品的 models/item/.json)插进输入框;设置改完还能一键把"改了什么"连同 mc-art.settings.json 一起插进去。
- ⚙ 设置:参考目录(游戏目录或某个版本目录)、已产出的贴图是否也当参考、逐个模组开关。

面板只写三个接口:atlas.saveTexture / atlas.saveVoxel / atlas.saveSettings,且只写进项目自己的包,从不写进 jar。完整说明书:skills/mc-mod/references/panel.md。

二、判定:让游戏自己说

GameTestServer 跑完注册的测试就退出,退出码 = 失败的必要测试数量。
本仓库实测(Forge 1.18.2 / 40.2.0):

| 跑法 | 服务端说 | 退出码 |
| 正常 | All 2 required tests passed :) | 0 |
| --fault(把断言改错) | fleshblockplaces failed! 放下去的血肉块不是血肉块 at 1,-59,1 (relative: 1,1,1) + 1 required tests failed :( | 1 |

首次构建约 26 分钟(Gradle + MC/Forge 依赖 + 450 MB 资源),之后每次约 1 分钟。

cd fleshland/mod
python ../../tools/mcmod_gametest.py # 裁决 + 机器可读 JSON
python ../../tools/mcmod_gametest.py --fault # 必须失败,否则这个闭环是摆设

三、快速开始

1. 一条命令装好

git clone https://github.com/GMH13552/dsh-mc-art.git
sh dsh-mc-art/install.sh # Windows: dsh-mc-art\install.bat

它做五件事:装 mc-mod;把美术引擎 mc-art 拉下来(已存在就 git pull --ff-only);把面板加载器里的 MCART_HOME 指向这次克隆的真实路径(不用再手改);装模式 mc-studio;自检依赖(Python / Pillow / JDK)。可重复执行。

面板有两种装法(同一份源码,panel/ 里是真包):

dsh plugin --profile web add "$PWD/panel" # 真包:重启 DSH 就在,不用发射

或者用动态插件(loader.host.js + loader.client.js 交给 cordis_define/cordis_run)——模式的人格已经写了会话开始时自己拉起来,不用等你开口。
之所以还要发射,是因为它现在是动态插件——重启就没了。要做到"重启就在",得按官方那条文件级插件路径打包(package.json 的 exports["./client"] + dsh.client 元数据,再用 dsh plugin --profile add),那是一次独立的打包工程。

sh install.sh --no-cordis-tools # 把模式里的 Cordis 工具行关掉(见第四节的限制)

美术引擎不是子模块,但它会被自动装。 install.sh 会 clone(或更新)它。
为什么不做成 git submodule:它有自己的仓库、历史和节奏,本来也独立可用(一台确定性引擎);子模块会把它钉在某个 commit 上(更新要手动 bump),而最常见的坑是 git clone 忘了 --recursive —— "装好了"却少了半个引擎。想手动装也一样:
git clone https://github.com/GMH13552/mc-art.git ~/.dsh/skills/mc-art

2. 用面板(作为 DSH 动态插件)

面板由一次 cordis_define 定义、cordis_run 激活。但发射的不是整个插件源码,而是一个加载器(loader.host.js + loader.client.js,各约 1.3 KB)——它在激活时从仓库读 host.js / client.js 并执行。好处:改界面不用再把 200 多 KB 逐字重打一遍,重跑同一个包即可。

⚠️ 安装时改一处:loader.host.js 顶部的

const MCART_HOME = '/你的克隆路径/dsh-mc-art/tools/mcart-plugin' // 安装器会自动改写这一行

改成你自己的克隆路径;把它的内容作为 code.host、loader.client.js 作为 code.client 交给 DSH 的 cordis_define,再 cordis_run。

代价说清楚:运行的就是磁盘上那份源码——审批粒度从"这一份代码"变成"那个文件以后的内容"。

3. 依赖

| 需要 | 用来做什么 |
| Node + DeepSeek Harness | 跑面板插件 |
| Python 3.10+ | 抽取器、扫描器、判定工具 |
| JDK 17 | 编译/运行 1.18.2 的模组(1.20.5+ 要 21) |
| 一份 Minecraft 安装 | 当参考目录:原版/模组的模型与贴图从那里读 |

四、作为独立模式(agent preset)

presets/mc-studio/ 是一个 agent preset(模式):装好之后,模式选择里就有 MC 模组工作室。它 = 完整编码/文件/命令能力 + 两个 skill 的路由 + 一段"工作室"人格(先读 mc-mod/mc-art、面板从哪来、裁判怎么跑、版本矩阵在哪)。

node install.mjs # 或 sh install.sh / install.bat:装 skill + 模式 + 面板包

这个模式刻意不带 tool-cordis。 那套工具集能动态挂载插件,但它注册的 Host Inspect provider 是进程级的:同一进程里已经有别的会话用着它时,这一行会挂载失败并报 Host Cordis inspect provider "Service" is already registered(实测;出厂的创造模式用的是同一行、同一个注册表)。面板因此改由装进 profile 的真包提供(见第五节),模式自己不需要那套工具集——于是"完整 / 无 Cordis"两个模式并成了一个。要改面板源码,用仓库里的 loader 动态发射一次(开发用,见 panel/README.md)。门禁 node tools/check_presets.mjs 盯着"别把那一行加回来"。

升级插件后必须彻底退出应用(关窗口不够)

宿主那一半(mcart-panel 那一行)是进程启动时挂载的:升级只换了磁盘上的文件,老进程里挂着的那份宿主还活着,于是你会看到"客户端是新的、宿主是旧的"这种怪事 ——实测症状:面板报 宿主没有这个方法:atlas.pickDirectory,而在别的启动顺序下同一个包一切正常。

- Electron 桌面端:任务管理器里把 DeepSeek Harness.exe 及其子进程都结束掉,再启动(托盘常驻时关窗口不算退出)。
- 命令行起的 web:Ctrl-C 那个进程即可,然后重新 dsh web。

判据很简单:换了包版本 → 必须重启进程。客户端那半会热重载,宿主那半不会。

两代 DSH 对"预设"的模型不一样(踩过)

| | 0.1.x(本仓库开发用的这套) | 0.2.0-rc.x(Windows 桌面端) |
| 包 | dsh-agent-presets(复数) | dsh-agent-preset(单数)+ …-registry |
| 预设从哪来 | 扫目录:.agent-presets/、包内 root(roots 键) | 组合里的行:@deepseek-ai/dsh-agent-preset,config = {id,name,description,order,plugins} |
| 注册表 Config | roots / includeShippedRoot / includeUserRoot | 只有 default / selectedDefault(没有 roots) |

所以"包内 preset/ + 给 agent-presets 行加一个 root"这招在桌面端会无声失效(它打在一个不存在的行 id 上,而我们验证过"打不存在的行无害")。同一批行换一种送达方式就行: presets/mc-studio/desktop-generation.patch.yml 是把源预设的 18 行包成一条 @deepseek-ai/dsh-agent-preset(skill 那行指到装好的包 node_modules/dsh-mc-art-panel/preset/mc-studio/skills),追加到该 profile 的 cordis.patch.yml 末尾、重启即生效。⚠️ 这份是手工生成的(还没接进 build.mjs),改源预设时要一起重新生成。
(另:桌面端那代的 skill 根照旧扫 ~/.dsh/skills,所以 skill 只靠用户目录也能送达。)

五、DSH 插件

面板在 npm 上叫 dsh-mc-art-panel,而且它不只是面板:包里同时带着「MC 模组工作室」模式和两个 skill(mc-mod + mc-art),装一个包就全有 —— 不用再跑安装器,也不往用户目录写东西。
别人拿到它有三条路,都验证过:

一条命令装好(已发布到 npm:dsh-mc-art-panel@0.1.0):

dsh plugin --profile web add dsh-mc-art-panel
(桌面端 profile 通常叫 desktop:--profile desktop)国内想走镜像:加 --registry=https://registry.npmmirror.com/ ⚠️ 镜像是只读同步、而且会滞后(实测 0.1.25 发布后十几分钟镜像上还没有):装之前先 npm view dsh-mc-art-panel version --registry=https://registry.npmmirror.com/ 看它到底追到哪一版;没追上就用下面的 release tarball(那条是即时的)。
不想依赖 npm:dsh plugin --profile web add \
https://github.com/GMH13552/dsh-mc-art/releases/latest/download/dsh-mc-art-panel.tgz
重启 DSH → 右侧栏出现「MC 资产」

| 怎么给 | 别人怎么装 | 备注 |
| npm 包名(现在走这条) | 插件对话框里填 dsh-mc-art-panel,或上面那条命令 | 实测:装完 bundles 里有它、组合里有 - id: mcart-panel;npmmirror 会滞后,别按它判断有没有新版 |
| Release tarball | 上面注释里那条 URL | 不需要 npm 账号;文件名不带版本号 + releases/latest/download/ = 命令永久有效 |
| 本地目录 | dsh plugin --profile web add /path/to/dsh-mc-art/panel | 克隆了仓库的人 / 改面板源码时用 |

打包与发版(我这边已经做过一次,记下来):

cd panel && npm pack --pack-destination /tmp # 出 dsh-mc-art-panel-0.1.0.tgz
gh release create v0.1.0 /tmp/dsh-mc-art-panel-0.1.0.tgz --title … --notes …
cp /tmp/dsh-mc-art-panel-0.1.0.tgz /tmp/dsh-mc-art-panel.tgz
gh release upload v0.1.0 /tmp/dsh-mc-art-panel.tgz --clobber # 不带版本号的那份,给 latest/download 用

⚠️ 不要填本仓库的 GitHub 地址:包在 panel/ 子目录里,pnpm 会把整个仓库当成一个 0.0.0 的空包装上(不报错),但它没有 dsh.bundle.patch,于是不会进 bundle 栈——用户看到的是“装好了但什么都没发生”。DSH 判定“装上来的算不算插件”看的就是这一条。

发布(需要你的 npm 账号,本机 npm adduser 之后):

cd panel
npm version patch # 或 minor/major;版本号是别人升级的唯一线索
npm publish # prepublishOnly 会先跑 verify-build + entry-test,漂移就发不出去
npm view dsh-mc-art-panel version # 回读确认

发完之后,node install.mjs --panel-spec dsh-mc-art-panel 就是纯 npm 路径了(默认仍用本地目录,这样克隆仓库的人离线也能装)。DSH 目前不支持插件自动更新,升级 = 改版本号重发,别人重新装。

发布这件事上的几个坑(都值得先说清):

- 装不用登录,发必须登录,而且要一个邮箱已验证的免费账号:。
命令行侧 npm login(npm 9+ 默认走浏览器授权:它打印一个网址,在浏览器里点一下即可; WSL 里自动开浏览器可能失败,把网址复制到 Windows 浏览器打开也一样)。
- 不想走浏览器就用 Token:网页 → 头像 → Access Tokens → Generate New Token(发布用 Automation 类型),然后 npm config set //registry.npmjs.org/:_authToken=。
开了 2FA 时这条最省事(否则每次发布都要 OTP)。Token 是密码级的东西,别提交进仓库。
- 发布只能去官方 registry:registry.npmmirror.com 是只读镜像,往那儿 publish 会被拒。
如果你为装包把 registry 换成了镜像,发布时要显式指回官方:
npm publish --registry https://registry.npmjs.org/。
- 名字被占就加 scope:@你的用户名/dsh-mc-art-panel。客户端注册的 id 是从 package.json 的 name 读的,所以改名后 id 自动跟着变(不用动代码);publishConfig.access: public 已经设好了(scoped 包不加这个会被当成私有、发不出去)。

- GitHub topics:dsh-plugin、deepseek-harness、cordis-plugin、agent-skill、 minecraft、minecraft-mod、gametest
- 形态:DSH 动态 Cordis 插件(host 半 + client 半)。两半由 new Function 编译,所以运行时注入的绑定必须逐个显式传参(host:harness/console/TextEncoder/btoa/atob; client:React/host/styles/console)——少一个就会在浏览器页里炸,而那边只能看到 Run 卡片上一句 x is not defined。
- 门禁:node tools/mcart-plugin/loader-test.js 用真实的两个半文件跑通加载器,并注入“少传一个绑定”证明它会当场炸。
- 真包形态与“送达”门禁:panel/ 是同一份源码包成的真包(dsh plugin --profile web add )。
它有五道门:verify-build.mjs(挡漂移)、entry-test.mjs(两个入口真的装载,--fault 会红)、 strip_gate.py(注释剥离器不许吞代码:声明的名字一个都不能少,--fault 做 A/B 证明能红)、 serve-check.mjs(对着跑着的实例查启动图 + bundle 字节 + 真浏览器里的激活痕迹)。
第三道不是装饰:客户端 bundle 必须注册成包名,早先抄错成宿主行的名字,包能装、前两道全绿,页面上却什么都不出现。细节见 panel/README.md。

六、通用流程与版本

- 流程(七阶段):定目标 → 定有什么 → 出美术 → 写 atlas → 生成代码/资源 → 游戏内验证 → 人眼验证 → 分支与移植,每阶段写清“什么算过”: skills/mc-mod/references/workflow.md
- 版本矩阵:≤1.12.2 没有 GameTest(只有“能编译、服务端起来、日志干净”); Forge 的 GameTest 要 1.18.1+ / 39.0.88+;1.18.2 实测 Java 17 / DataVersion 2975 / pack_format 9-8-9;“怎么查而不是猜”(读 version.json、javap 映射 jar): skills/mc-mod/references/versions.md
- Windows(原生,不需要 WSL):安装用 install.bat(POSIX 用 sh install.sh,两者都是薄壳,逻辑在同一份 install.mjs 里)。要注意三件事,都是实测过的:
1. Python 的名字:Windows 上没有 python3,装完叫 python 或 py。面板宿主、三门禁、GameTest 工具都会自己探测(python3 → python → py -3),你只要让它进 PATH。
2. shell 不是 bash:DSH 在 win32 上把 bash 那几行 disabled、启用 PowerShell (dsh-base 的 cordis.patch.yml)。所以面板里所有 shell 命令都按方言拼(rm -f/mv -f/$(printf|base64 -d) → Remove-Item/Move-Item/.NET),门禁 node tools/mcart-plugin/shell-dialect-test.js 会把捕获到的命令交给真的 Windows PowerShell 执行来验(本机跑过:12 项全绿;谎报方言则 8 项红)。
3. JDK 版本要对:1.18.2 的模组要 JDK 17;只有 21 会在 Gradle/Forge 配置阶段就失败。
./gradlew 在 Windows 上是 gradlew.bat,tools/mcmod_gametest.py 自己会选。

七、实测记录(不是宣传)

- GameTest:正常绿 / 注入红(见上表)。
- 正交相机的贴图插值:条纹宽度 1.03(正确)vs 2.81(旧的透视插值,远侧压到一半)。
- 面板点击偏移:盒子比画宽时,点“画出来的左边缘”会被算成第 4 格(该是第 0 格)。
- 平铺图标曾因“依赖活的 ”而全空(0 像素),立方体不受影响。

八、没包含什么

- 美术引擎(mc-art)的副本 —— 它在自己的仓库里。
- 本地美术项目与个人笔记:这是工具仓库,不带创作数据。
- fleshland/mod/ 故意不带资源:一个命名空间有两份资源就是两个真相;模组工程里的那份资源应当由 datagen 从 atlas 生成。

相关仓库

- GMH13552/mc-art —— 美术 skill(确定性引擎)
- GMH13552/mc-art-pipeline —— 旧架构,已归档
- GMH13552/dsh-longrun-suite、 GMH13552/dsh-timer-scheduler —— 其他 DSH 插件

许可

未附许可证。要开源请加一个 LICENSE(例如 MIT)。
预览分享卡片长什么样 ↓GMH13552/dsh-mc-art
分享 · DeepSeek Harness Hub
GMH13552/dsh-mc-art

从描述生成可验证的 Minecraft 模组并自动判定

这是你的仓库?认领条目

回到顶部